Using margin:auto to vertically-align a div
Update Aug 2020
Although the below is still worth reading for the useful info, we have had Flexbox for some time now, so just use that, as per this answer.
You can't use:
vertical-align:middle
because it's not applicable to block-level elements
margin-top:auto
and margin-bottom:auto
because their used values would compute as zero
margin-top:-50%
because percentage-based margin values are calculated relative to the width of containing block
In fact, the nature of document flow and element height calculation algorithms make it impossible to use margins for centering an element vertically inside its parent. Whenever a vertical margin's value is changed, it will trigger a parent element height re-calculation (re-flow), which would in turn trigger a re-center of the original element... making it an infinite loop.
You can use:
A few workarounds like this which work for your scenario; the three elements have to be nested like so:
.container {
display: table;
height: 100%;
position: absolute;
overflow: hidden;
width: 100%;
}
.helper {
#position: absolute;
#top: 50%;
display: table-cell;
vertical-align: middle;
}
.content {
#position: relative;
#top: -50%;
margin: 0 auto;
width: 200px;
border: 1px solid orange;
}
<div class="container">
<div class="helper">
<div class="content">
<p>stuff</p>
</div>
</div>
</div
Why doesn't margin: auto center an element vertically?
As mentioned, this behavior is specified in section 10.6.2 of CSS2.1, and has remained unchanged from CSS2.
Block boxes are stacked vertically from top to bottom in normal flow. Furthermore, vertical margins may collapse, and only do so under certain circumstances (in your demo, the border on the parent element will prevent any margins on the child element from collapsing with its own). If you only have one such block box, and the height of the containing block is auto, then its top and bottom margins will be zero anyway. But if you have more than one block box in the same flow, or even out-of-flow boxes affecting the layout of in-flow boxes (in the case of clearance for example), how would you expect auto margins to resolve for those in-flow boxes?
This is why auto left and right margins are likewise zeroed out for inline elements (including atomic inlines) and floats (though horizontal margins never collapse). Inline-level boxes are laid along line boxes, and floats too obey unique layout rules.
Absolutely positioned boxes are a different story: since they are never aware of any other boxes in the same positioning context as themselves, auto top and bottom margins can be calculated for them with respect to their containing blocks without having to worry about any other boxes ever interfering.
Flexbox is also a different story: what sets flex layout apart from block layout is that flex items are by definition always aware of other flex items in the same flex formatting context, including the fact that there are none. In particular, neither can floats intrude into the flex container, nor can you float flex items to subvert this (although you can still remove a child element from flex layout completely with absolute positioning). Margins behave very differently with flex items due in part to this. See sections 4.2, 9.5 and 9.6.
Why does margin: auto only work horizontally and not vertically?
It's really less of a nightmare than you think, just don't use margins. vertical-align
is really what you should rely on for fluid-height vertical centering. I threw together a quick demo to demonstrate my point:
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
text-align: center;
}
span {
height: 100%;
vertical-align: middle;
display: inline-block;
}
#any-height {
background: #000;
text-align: left;
width: 200px;
height: 200px;
vertical-align: middle;
display: inline-block;
}
<span></span>
<div id="any-height"></div>
Why don't margin-top: auto and margin-bottom:auto work the same as their left and right counterparts?
The short answer is the spec says so.
10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block' replaced elements in normal flow and floating replaced elements
If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
http://www.w3.org/TR/CSS2/visudet.html#Computing_heights_and_margins
margin : auto not working vertically?
margin:auto
can center vertically only absolutely positioned elements with known height (fiddle):
.container {
position: relative;
}
.centered {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
}
Using Margin: auto; is not centering div
Okay, the way I fixed it is by changing the HTML and CSS
From <div class="col-md-3 sub admin">
to <div class="col-sm-3 admin">
I'm not totally sure if that contributed, but ¯_(ツ)_/¯
Then I changed the CSS to
.users {
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
margin: auto;
}
.admin {
max-width: 410px;
margin-left: 10px;
margin-top: 5px;
margin-bottom: 5px;
border-style: solid;
border-width: 1px;
border-color: grey;
box-shadow: 2px 2px 1px grey;
background: white;
background: -webkit-linear-gradient(#fff , #F1F1F1);
background: -o-linear-gradient(#fff , #F1F1F1);
background: -moz-linear-gradient(#fff , #F1F1F1);
background: linear-gradient(#fff , #F1F1F1);
}
The only problems are that it looks a bit funky on tablet sized screens, and that it's not totally centralised. However, it works for now.
Why margin auto in flex makes vertical and horizontal centered
The functionality of the flex calculating the margin in all direction based on the parent div height and width,
i.e
The div#one having the height&width of 300px
The div#two having the height&width of 100px
so the margins are calculated as margin:100px;
Which means
#two{
margin-top:100px;
margin-right:100px;
margin-bottom:100px;
margin-left:100px;
}
If you need only horizontal margin then use margin:0 auto;
margin auto not working after vertical aligning
To center both vertically and horizontally following your attempt, try this:
// assumed positioned element
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
Reference, and another good resource.
Related Topics
How to Make Scrollable Table with Fixed Headers Using CSS
Css3 Transition Doesn't Work with Display Property
Required Attribute Not Work in Safari Browser
How to Post/Submit an Input Checkbox That Is Disabled
How to Rotate and Postion an Element on the Top Left or Top Right Corner
Best Way to Synchronize Local HTML5 Db (Websql Storage, SQLite) with a Server (2 Way Sync)
Make Div's Height Expand with Its Content
How to Auto-Format/Indent Xml/HTML in Notepad++
How to Hide HTML Source & Disable Right Click and Text Copy
Preventing Firefox from Remembering the Input Value on Refresh with a Meta Tag
Why Are Frames Deprecated in HTML
Using Base Tag on a Page That Contains Svg Marker Elements Fails to Render Marker
How to Center an Unordered List
Html5 New Elements (Header, Nav, Footer, ..) Not Working in Ie
Position: Sticky' Not Working When 'Height' Is Defined
Display HTML Child Element When Parent Element Is Display:None