Why doesn't margin 0 auto work? Centering absolutely positioned elements


Description

Sets the amount of padding from each edge of the element. The margin is the space from the border of the current element to the inner border of its parent element (Fig. 1).

Rice. 1. Indent from the left edge of the element

If the element does not have a parent, the padding will be the distance from the edge of the element to the edge of the browser window, taking into account that the window itself also has padding set by default. To get rid of them, you should set the margin value for the selector equal to zero.

The margin property allows you to set the margin value for all sides of an element at once or define it only for specified sides.

Syntax

margin: [value | interest | auto] (1,4) | inherit

Values

You can use one, two, three or four values, separated by a space. The effect depends on the number of values ​​and is shown in table. 1.

The amount of indentation can be specified in pixels (px), percentage (%) or other acceptable values. CSS units. The value can be either a positive or negative number.

Auto Specifies that the indent size will be automatically calculated by the browser. inherit Inherits the value of the parent.

HTML5 CSS2.1 IE Cr Op Sa Fx

margin

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

Result this example shown in Fig. 2.

Rice. 2. Applying the margin property

Object model

document.getElementById("elementID ").style.margin

Browsers

Internet Explorer 6 in compatibility mode (quirk mode) does not support centering the block using the margin: 0 auto rule. There is also a bug in this browser with doubling the left or right padding value for floated elements nested within parent elements. The margin that is adjacent to the parent's side is doubled. The problem is usually solved by adding display: inline to the floated element.

Internet Explorer versions up to and including 7.0 do not support the inherit value.

Note

For block elements located next to each other vertically, a collapsing effect is observed when the indents are not summed up, but combined with each other. The collapse itself acts on two or more blocks (one can be nested inside another) with indents at the top or bottom, while adjacent indents are combined into one. For left and right padding, collapsing is never applied.

Collapse does not work:

  • for elements that have the padding property set on the collapsing side.
  • for elements that have a boundary specified on the collapsing side;
  • on elements with absolute positioning, i.e. those whose position is set to absolute ;
  • on floating elements (for them float property given as left or right );
  • for inline elements;
  • For .

Internet Explorer is a problem that ruins the lives of most web developers. More than 60% of development time may be spent solving these specific problems, which is not effective use time. In this article I will talk about the most popular bugs and inconsistencies in positioning, as well as how to most easily solve these problems.

1. Center positioning.

Every web developer, when laying out a website, was faced with the need to align an element in the center. The simplest and most popular way is to write margin: auto; . This method allows you to center an element regardless of screen resolution. However, this method does not work in IE6.

Consider the following code:

#container ( border: solid 1px #000; background: #777; width: 400px; height: 160px; margin: 30px 0 0 30px; ) #element ( background: #95CFEF; border: solid 1px #36F; width: 300px; height: 100px; margin: 30px auto; )

Expected Result:

However, Internet Explorer will show you the following:

This happens because IE6 does not recognize the auto value set. margin property. Fortunately, this is easy to fix.

Let's fix it.

The simplest and most proven way to center an element in IE6 is to write text-alignL center on the parent element and apply tex-align: left to it itself so that its contents are aligned correctly.

#container( border: solid 1px #000; background: #777; width: 400px; height: 160px; margin: 30px 0 0 30px; text-align: center;) #element( background: #95CFEF; border: solid 1px #36F; width: 300px; height: 100px; margin: 30px 0; text-align: left; }

2. Step effect

Almost every developer uses lists to create navigation. Typically, a container element is created, the necessary links are inside it, and then the float property is set with the required direction. Consider the following example:

Ul ( list-style: none; ) ul li a ( display: block; width: 130px; height: 30px; text-align: center; color: #fff; float: left; background: #95CFEF; border: solid 1px # 36F; margin: 30px 5px; )

We get the following:

However, IE will show us:

Not very friendly navigation, is it? However, there are 2 ways to fix this unpleasant behavior.

1st method

The simplest way is to set the float property not to links, but to elements of the li list.

Ul li ( float: left; )

2nd method

The second way is to apply the display: inline property to the li element. Additionally, we are fixing a bug with double margin, which is described below.

Ul li (display: inline)

3. Double indentation for elements with the float property set

It's very easy to reproduce this error. Set the element to float: left and then padding. As a result, we get an indentation twice as large as specified.

Let's look at an example:

#element( background: #95CFEF; width: 300px; height: 100px; float: left; margin: 30px 0 0 30px; border: solid 1px #36F; )

Expected Result:

However, in IE6 we will see the following:

We fix it

This is corrected in the same way as the problem with the effect of steps. That is, we set the display: inline property for the element. Our code will change like this:

#element( background: #95CFEF; width: 300px; height: 100px; float: left; margin: 30px 0 0 30px; border: solid 1px #36F; display: inline; }

4. Elements with small height.

Sometimes it is necessary to create elements with a small height, for example to use them as a design element. The first way that came to mind was to set the height. However, IE will not show you what you expect.

The result is an element with a height of 2px and a border of 1px.

Let's fix it.

The reason for this bug is very simple: IE simply changes the height of the element to a height equal to the font size. Thus, we simply set the font size to zero.

#element( background: #95CFEF; border: solid 1px #36F; width: 300px; height: 2px; margin: 30px 0; font-size: 0; }

Second approach

Another good way- this is to use the overflow property, you need to apply the hidden value. And then the element will be of the required height.

#element( background: #95CFEF; border: solid 1px #36F; width: 300px; height: 2px; margin: 30px 0; overflow: hidden; }

5. Overflow and relative positioning of elements.

This bug occurs when the parent element has the overflow: auto property set, and the child is positioned relative to it, that is, its position: relative property is set. It turns out that child element is located, as it were, on top of the parent. Let's look at an example:

#element( background: #95CFEF; border: solid 1px #36F; width: 300px; height: 150px; margin: 30px 0; overflow: auto; ) #anotherelement( background: #555; width: 150px; height: 175px; position : relative; margin: 30px; )

Expected Result:

Result in IE:

Let's fix it.

The simplest way to solve the problem is to give the parent element a relative positioning.

#element( background: #95CFEF; border: solid 1px #36F; width: 300px; height: 150px; margin: 30px 0; overflow: auto; position: relative; }

6.Box Model

Internet Explorer incorrectly interprets the box model.

For example there are 2 div element. One with the bug fixed and the other not. There will be a difference in size between them equal to the sum of the internal paddings.

We fix it

I’ll tell you about the correct model in another article, but now I’ll just show you how to fix it.

The point is that for IE5/6 the height and width must be set separately. For example, I do it like this:

For all browsers

#element( width: 400px; height: 150px; padding: 50px; )

For IE you need to do this:

#element ( width: 400px; height: 150px; \height: 250px; \width: 500px )

Essentially you are adding padding values ​​to the element's dimensions for IE6.

7. Setting minimum sizes.

Minimum width and height are simply irreplaceable when creating a beautiful design. Unfortunately, IE ignores the min-height and min-width properties.

We fix it

To solve the problem, let's use the!important identifier.

#element ( min-height: 150px; height: auto !important; height: 150px; )

Second option.

If we take into account the fact that IE does not understand nested selectors, then we can do this:

#element ( min-height: 150px; height: 150px; ) html>body #element ( height: auto; )

8. Incorrect behavior in the float model.

One of the most important concepts in tableless layout using CSS is float. Most of the time IE6 handles this correctly, but sometimes there are problems. For example, when the content is non-breaking or the width of the element is greater than the width of the parent. In these cases, the markup breaks. Let's see an example.

http://net.tutsplus.com/

#element, #anotherelement( background: #95CFEF; border: solid 1px #36F; width: 100px; height: 150px; margin: 30px; padding: 10px; float: left; ) #container( background: #C2DFEF; border: solid 1px #36F; width: 365px; margin: 30px; padding: 5px; overflow: auto; )

Got it in IE:

As you can see, the first div has expanded to fit the content width and pushed the adjacent one onto the next line.

We fix it

There is no beautiful solution. But you can, for example, apply the overflow: hidden property, but then the content will be cut off and part of it will not be visible.

#element( background: #C2DFEF; border: solid 1px #36F; width: 365px; margin: 30px; padding: 5px; overflow: hidden; )

9. Extra space between list items.

IE 6 adds extra padding to vertical lists. Let's look at an example.

  • Link 1
  • Link 2
  • Link 3

Ul ( margin:0; padding:0; list-style:none; ) li a ( background: #95CFEF; display: block; )

What it should look like:

What IE shows:

1st method

The easiest way is to specify the width or height for the link.

Li a ( background: #95CFEF; display: block; width: 200px; }

2nd method

The next way is to set float: left and then clear it.

Li a ( background: #95CFEF; float: left; clear: left; }

3rd method

The third way is to set display: inline on the li element. Which, by the way, will fix the double margin error described above.

How many copies have already been broken about the task of aligning elements on a page. I bring to your attention a translation of an excellent article with a solution to this problem from Stephen Shaw for Smashing Magazine - Absolute Horizontal And Vertical Centering In CSS.

We all knew about margin: 0 auto; for horizontal centering, but margin: auto; didn't work for vertical. This can be easily fixed by simply setting the height and applying the following styles:

Absolute-Center ( margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; )
I'm not the first to propose this solution, but this approach is rarely used when vertical alignment. In the comments to the article How to Center Anything With CSS, Simon links to a jsFiddle example that provides a great solution for vertical centering. Here are a few more on this topic.

Let's take a closer look at the method.

Advantages

  • Cross-browser compatibility (including IE 8-10)
  • No additional markup, minimal styling
  • Adaptability
  • Independence from padding(without box-sizing!)
  • Works for images

Flaws

  • The height must be specified (see Variable Height)
  • It is recommended to set overflow: auto so that the content does not spread
  • Doesn't work on Windows Phone

Browser compatibility

The method has been tested and works great in Chrome, Firefox, Safari, Mobile Safari and even IE 8-10. One user mentioned that content is not vertically aligned on Windows Phone.

Inside the container

Content placed in a container with position: relative will align perfectly:

Absolute-Center ( width: 50%; height: 50%; overflow: auto; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; )

Using viewport

Let's set the content to position: fixed and set the z-index:

Absolute-Center.is-Fixed ( width: 50%; height: 50%; overflow: auto; margin: auto; position: fixed; top: 0; left: 0; bottom: 0; right: 0; z-index: 999; )

Adaptability

The main advantage of the described method is that it works perfectly when the height or width is specified as a percentage, and even understanding min-width/max-width And min-height/max-height.

Absolute-Center.is-Responsive ( width: 60%; height: 60%; min-width: 400px; max-width: 500px; padding: 40px; overflow: auto; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; )

Offsets

If the site has a fixed header or you need to make some other indentation, you just need to add code like this to the styles top: 70px; Currently set margin: auto; the content block will be correctly centered in height.

You can also align the content to the desired side, leaving centering in height. To do this you need to use right: 0; left: auto; for right alignment or left: 0; right: auto; for left alignment.

Absolute-Center.is-Right ( width: 50%; height: 50%; margin: auto; overflow: auto; position: absolute; top: 0; left: auto; bottom: 0; right: 20px; text-align: right; )

Lots of content

To ensure that a large amount of content does not allow the layout to move apart, we use overflow: auto. A vertical scrollbar will appear. You can also add max-height: 100%; if the content does not have additional padding.
.Absolute-Center.is-Overflow ( width: 50%; height: 300px; max-height: 100%; margin: auto; overflow: auto; position: absolute; top: 0; left: 0; bottom: 0; right : 0; )

Images

This method works great for images too! Let's add style height: auto; then the image will scale along with the container.

Absolute-Center.is-Image ( width: 50%; height: auto; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; )

Variable height

The described method requires a given block height, which can be specified as a percentage and controlled using max-height, which makes the method ideal for responsive websites. One way to not specify a height is to use display: table. In this case, the content block is centered regardless of size.

There may be problems with cross-browser compatibility, perhaps you should use the table-cell method (described below).

  • Firefox/IE8: usage display: table Aligns the block vertically to the top border of the document.
  • IE9/10: usage display: table aligns the block left top corner pages.
  • Mobile Safari: if the width is set to a percentage, horizontal centering suffers
.Absolute-Center.is-Variable ( display: table; width: 50%; overflow: auto; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; )

other methods

The described method works great in most cases, but there are other methods that may be applicable to solve specific problems.

Negative margin

Probably the most popular way. Suitable if the block dimensions are known.

Is-Negative ( width: 300px; height: 200px; padding: 20px; position: absolute; top: 50%; left: 50%; margin-left: -170px; /* (width + padding)/2 */ margin- top: -120px; /* (height + padding)/2 */ )
Advantages:

  • Cross-browser compatibility
  • Minimum code
Flaws:
  • Not adaptive
  • Layout creeps if there is too much content in the container
  • You have to compensate for the indentation or use box-sizing: border-box

Using transform

One of the most simple ways, supports height change. There is a detailed article on this topic - "Centering Percentage Width/Height Elements" from CSS-Tricks.

Is-Transformed ( width: 50%; margin: auto; position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%,-50%); -ms-transform: translate( -50%,-50%); transform: translate(-50%,-50%); )
Advantages:

  • Variable height
  • Minimum code
Flaws:
  • Doesn't work in IE 8
  • Using Prefixes
  • May interfere with other effects with transform
  • In some cases, block edges and text are blurred during rendering

Table-cell

Perhaps one of the best and easiest ways. Described in detail in the article "Flexible height vertical centering with CSS, beyond IE7" by 456bereasttreet. The main drawback is the additional markup: three elements are required:

<!-- CONTENT -->

CSS:
.Pos-Container.is-Table ( display: table; ) .is-Table .Table-Cell ( display: table-cell; vertical-align: middle; ) .is-Table .Center-Block ( width: 50%; margin: 0 auto; )
Advantages:

  • Variable height
  • Layout does not work when large quantities text in block
  • Cross-browser compatibility
Flaws:
  • Complex structure

Flexbox

The future of CSS, flexbox will solve many of today's layout problems. This is written in detail in a Smashing Magazine article called Centering Elements with Flexbox.

Pos-Container.is-Flexbox ( display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-align: center; - moz-box-align: center; -ms-flex-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: center; -moz-box-pack: center; -ms-flex-pack: center; -webkit-justify-content: center; justify-content: center; )
Advantages:

  • Content can be any height or width
  • Can be used in more complex cases
Flaws:
  • No support for IE 8-9
  • Requires container or styles in body
  • Requires a wide variety of prefixes to correct operation in modern browsers
  • Possible performance issues

Bottom line

Each method has advantages and disadvantages. Essentially, the choice comes down to choosing which browsers should be supported

Using margin:auto to center a block element horizontally is a well-known technique. But have you ever wondered how it works?

The effect of auto depends on the element type and context. For top padding CSS auto can mean one of two things: take everything free space or 0 pixels. Depending on this, a different structure will be specified.

"auto" - occupy all available space

This is the most common way to use auto for indentation. If we set auto for the left and right padding of one element, they will evenly take up all the horizontal space available in the container. This will position the element in the center.

View example

This only works for horizontal padding. But will not work for floated and inline elements. And also for absolutely and fixedly positioned elements.

Simulate floating behavior by allocating available space

auto distributes all free space equally between the right and left margins. But what happens if we set this value for only one of the paddings? Then it will take up all the available space, and the element will be offset to the right or left edge.

View example

“auto” — set 0 pixels

As mentioned above, auto doesn't work for floated, inline, or absolutely positioned elements. A structure has already been defined for them, so in use margin auto it makes no sense.

This will only disrupt the original structure. Including CSS for indenting text at the top. Therefore, auto will set the padding of these elements to 0 pixels.

auto will also not work on a standard block element unless it has a width specified. In all the examples I gave, the elements had a width specified.

The value auto will define a padding of 0 pixels when the width of a block element is set to auto or 100% . Typically it takes up the entire width of the container, so there will be 0 pixels left for the padding width.

What happens to vertical padding when set to auto?

auto for both CSS top padding and bottom padding is always calculated as 0 pixels ( excluding absolutely positioned elements). The W3C specification states the following:

"If 'margin-top' or 'margin-bottom' is set to 'auto', they are set to 0."

This is due to the fact that on a web page, all elements are most often distributed vertically. Therefore, by centering an element height in a container, we will not achieve the fact that it will appear vertically centered relative to the page itself, as happens with horizontal centering.

Or maybe it's for the same reason that they decided to add an exception for absolutely positioned elements that can be centered vertically relative to the overall page height.

Or because the effect of combining indents (merging indents of adjacent elements). This is another exception to of this rule determining vertical offsets.

Centering absolutely positioned elements

Since there is an exception for absolutely positioned elements, you can use auto to center them vertically and horizontally. But first we need to figure out when margin:auto will work exactly like this for CSS top padding.

Another W3C specification says:

“If all three positions (“left”, “width” and “right”) are set to “auto”, first set “margin-left” and “margin-right” to 0...
» If "auto" is specified only for "margin-left" and "margin-right", then solve the equation with additional condition so that both paddings have the same width."

The situation regarding the auto value for horizontal padding is described here in some detail. To ensure that these paddings are the same size, left , width , and right should not be set to auto ( their default value). To center an element horizontally, you need to set the width of the absolutely positioned element to a certain value, and left and right must have equal values.

In the specification also mentioned something similar for the top padding of the CSS div.

"If 'top', 'height' and 'bottom' are set to 'auto', set 'top' to static..."

"If one of the three positions is not set to 'auto': If 'top' and 'bottom' are set to 'auto', solve the equation with an additional condition to set these paddings to the same values."

Therefore, to vertically center an absolutely positioned element, top , height and bottom must not be set to auto .

Now, putting all this together, we get the following:

View example

Conclusion

If you need to move an element on a page to the right or left without container elements ( for example, as in the case of float), remember that you can use auto for indentation.

Converting an element to absolutely positioned only to center it vertically ( top padding CSS), Not best idea. There are other options such as flexbox and CSS transform that are better suited for this.

Translation of the article " CSS – margin auto – How it Works"was prepared by the friendly project team.

Good bad







2024 gtavrl.ru.