What, Exactly, Is Needed For "Margin: 0 Auto;" to Work

What, exactly, is needed for margin: 0 auto; to work?

Off the top of my head:

  1. The element must be block-level, e.g. display: block or display: table
  2. The element must not float
  3. The element must not have a fixed or absolute position1

Off the top of other people's heads:


  1. The element must have a width that is not auto2

Note that all of these conditions must be true of the element being centered for it to work.


1 There is one exception to this: if your fixed or absolutely positioned element has left: 0; right: 0, it will center with auto margins.

2 Technically, margin: 0 auto does work with an auto width, but the auto width takes precedence over the auto margins, and the auto margins are zeroed out as a result, making it seem as though they "don't work".

What does auto do in margin: 0 auto?

When you have specified a width on the object that you have applied margin: 0 auto to, the object will sit centrally within it's parent container.

Specifying auto as the second parameter basically tells the browser to automatically determine the left and right margins itself, which it does by setting them equally. It guarantees that the left and right margins will be set to the same size. The first parameter 0 indicates that the top and bottom margins will both be set to 0.

margin-top: 0;
margin-bottom: 0;
margin-left: auto;
margin-right: auto;

Therefore, to give you an example, if the parent is 100px and the child is 50px, then the auto property will determine that there's 50px of free space to share between margin-left and margin-right:

var freeSpace = 100 - 50;
var equalShare = freeSpace / 2;

Which would give:

margin-left: 25;
margin-right: 25;

Have a look at this jsFiddle. You do not have to specify the parent width, only the width of the child object.

CSS margin: 0 auto not centering

It is working.

The problem is you're centering a div, which is a block-level element by default, and which therefore occupies 100% width of its parent (body, in this case). So there's no space to move horizontally, hence no space to center.

For an illustration see this revised demo which has an added border around .container.

.container {
margin: 0 auto;
border: 1px solid red;
}

[class*='col-'] {
float: left;
}

.col-2-3 {
width: 66.66%;
}

.col-1-3 {
width: 33.33%;
}

.grid:after {
content: "";
display: table;
clear: both;
}

.col-word {
width: auto;
height: auto;
padding: 25px;
border: 5px #000 solid;
border-left: 0px;
border-right: 0px;
background-color: #A7F4F6;
font-size: xx-large;
text-align: center;
}
<div class='container'>
<div class="grid">
<div class='grid'>
<div class="col-1-3">
<p class='col-word'>T</p>
<p class='col-word'>V</p>
</div>
</div>
<div class='grid'>
<div class='col-1-3'>
<div class='letter'>W</div>
</div>
<div class='col-1-3'>
<div class='letter'>P</div>
</div>
<div class='col-1-3'>
<div class='letter'>V</div>
</div>
</div>
</div>
</div>

margin: 0 auto not working

Since you're using flexbox, you can add justify-content: center to your .item-list rules (no margin: auto needed):

.item-list {  display: flex;  justify-content: center;}
.item { margin-left: 10px; list-style: none;}
.item a { color: #37302b; font-size: 20px;}
header { position: inherit; height: 50px;}
<header>  <nav class="desktop-nav">    <ul class="item-list">      <li class="item active">        <a href="http://localhost:8888/gross-daily/main.html" data-scroll>Home</a>      </li>      <li class="item">        <a href="http://localhost:8888/gross-daily/main.html" data-scroll>Newest</a>      </li>      <li class="item">        <a href="#projects" data-scroll>Most Popular</a>      </li>      <li class="item">        <a href="#projects" data-scroll>Categories</a>      </li>      <li class="item">        <a href="#blog" data-scroll>Stash</a>      </li>      <li class="item">        <a href="#">Contact</a>      </li>      <li class="item" onclick="showSearch();">        <a href="#">Search</a>      </li>    </ul>  </nav></header>

Text-align:center and margin:0 auto not working on absolute positioned elements

Without changing the HTML, the easiest approach to center the element horizontally would be to combine left: 50% and transform: translateX(-50%). This will essentially position the element 50% to the right and then displace half of the element's width by transforming it -50% to the left. In doing so, the element will be centered horizontally regardless of the width which means that you don't need to hardcode any values.

position: absolute;
left: 50%;
transform: translateX(-50%);

Updated Snippet:

#wrap {  border: 1px solid black;  position: relative;  width: 500px;  margin: 0 auto;  height: 80px;}#absolute {  border: 1px solid red;  position: absolute;  transform: translateX(-50%);  left: 50%;  bottom: 0;  cursor: pointer;}
<div id="wrap">  <div id="absolute">Click Me</div></div>

CSS Margin: 0 is not setting to 0

Try...

body {
margin: 0;
padding: 0;
}

jsFiddle.

Because of browsers using different default stylesheets, some people recommend a reset stylesheet such as Eric Meyer's Reset Reloaded.

How to align a div to the middle (horizontally/width) of the page

<body>
<div style="width:800px; margin:0 auto;">
centered content
</div>
</body>

Why doesn't margin:auto center an image?

Because your image is an inline-block element. You could change it to a block-level element like this:

<img src="queuedError.jpg" style="margin:auto; width:200px;display:block" />

and it will be centered.

Center image horizontally within a div

#artiststhumbnail a img {
display:block;
margin:auto;
}

Here's my solution in: http://jsfiddle.net/marvo/3k3CC/2/

Using margin: 0 auto; in Internet Explorer 8

It is a bug in IE8.

Starting with your second question: “margin: 0 auto” centers a block, but only when width of the block is set to be less that width of parent. Usually, they get to be the same. That is why text in the example below is not centered.

<div style="height: 100px; width: 500px; background-color: Yellow;">    
<b style="display: block; margin: 0 auto; ">text</b>
</div>

Once the display style of the b element is set to block, its width defaults to the parents width. CSS spec 10.3.3 Block-level, non-replaced elements in normal flow describes how: “If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.” The equality mentioned there is

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

So, normally all autos result in a block width being equal to the width of containing block.

However, this calculation should not be applied to INPUT, which is a replaced element. Replaced elements are covered by 10.3.4 Block-level, replaced elements in normal flow. Text there says: “The used value of 'width' is determined as for inline replaced elements.” The relevant part of 10.3.2 Inline, replaced elements is: “if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'”.

I guess that the scenario CSS cares about is IMG element. Stackoverflow logo in this example will be centered by all browsers.

<div style="height: 100px; width: 500px; background-color: Yellow;">    
<img style="display: block; margin: 0 auto; " border="0" src="http://stackoverflow.com/content/img/so/logo.png" alt="">
</div>

INPUT element should behave the same way.



Related Topics



Leave a reply



Submit