How many times did you wrote
.container {
vertical-align: middle;
}
…and expected that all the children of the targeted elements will be centered vertically? And since it didn’t quite work as you expected, you made some people in headache pills industry very happy by buying their products in spite of the recession.
The answer is simple, it’s not supposed to work. At least, not like that.
Block and inline elements
There are basically two types of elements, based on the way that the browser will render them:
- block-level elements
- block-level elements can have width and height and when rendered they usually start with a new line. Examples of block-level elements are: divisions, paragraphs, headings 1 to 6 and so on
- inline elements
- inline elements don’t have width and height (setting the width or the height property will have no effect on the element’s layout) and are rendered inline, without any line breaks. Examples of inline elements are strong, emphasis, anchors etc.
Why is this important?
Vertical alignment
By default, the css vertical-align property refers to the position of inline elements regarding their direct parent’s line height. For instance
<p style="height: 20px;">
normal text
<span style="font-size: 10px; vertical-align: middle">vertical-align: middle</span>
normal text
<span style="font-size: 10px; vertical-align: top">vertical-align: top</span>
normal text
<span style="font-size: 10px; vertical-align: bottom">vertical-align: bottom</span>
</p>
…will produce…
normal text vertical-align: middle
normal text vertical-align: top
normal text vertical-align: bottom
This is how vertical align is supposed to work.
How about centering block elements?
Well, here things get a little more complicated. The vertical align centers block elements only if they’re within a table cell and the vertical-align property is applied to the table cell. Like so:
<table> <tr> <td style="vertical-align: middle"> <div>vertically aligned container</div> </td> </tr> </table>
In the above examples, all the elements within the table cell will be aligned vertically, whether they’re block-level or inline elements. So a tableless quick fix for the vertical alignment problem would be
.container {
display: table-cell;
vertical-align: middle;
}
…but the table-cell property isn’t supported by all the major browsers as you can see on this page. Of course, there are lots of hacks and tricks out there, that rely on absolute positioned elements, nifty javascripts and so on, but none of them proved really useful to me so far. I have the rare gift of finding the “chances of this happing are one to a million” situations and the css hack didn’t work for me. So whenever I need something to be positioned vertically, I use a table.
Sad but true. Lame but cross browser…
Lame but unavoidable, unfortunately