Using margin:auto to vertically-align a div

So I know we can center a div horizontally if we use margin:0 auto;. Should margin:auto auto; work how I think it should work? Centering it vertically as well?

Why doesn't vertical-align:middle; work either?

.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    background:yellow;
    width:200px;
    margin:auto auto;
    padding:10px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

JSFiddle


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

JSFiddle works fine according to Browsershot.


Since this question was asked in 2012 and we have come a long way with browser support for flexboxes, I felt as though this answer was obligatory.

If the display of your parent container is flex, then yes, margin: auto auto (also known as margin: auto) will work to center it both horizontally and vertically, regardless if it is an inline or block element.

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
}
#child {
    margin: auto auto;
}
<div id="parent">
    <div id="child">hello world</div>
</div>

Note that the width/height do not have to be specified absolutely, as in this example jfiddle which uses sizing relative to the viewport.

Although browser support for flexboxes is at an all-time high at time of posting, many browsers still do not support it or require vendor prefixes. Refer to http://caniuse.com/flexbox for updated browser support information.

Update

Since this answer received a bit of attention, I would also like to point out that you don't need to specify margin at all if you're using display: flex and would like to center all of the elements in the container:

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
    align-items: center; /* vertical */
    justify-content: center; /* horizontal */
}
<div id="parent">
    <div>hello world</div>
</div>