You might wonder why I'm writing this. It's been posted about time and time again, with various methods detailed in excellent blog posts, for example Gavin Kistner's post Understanding vertical-align, or "How (Not) To Vertically Center Content", but the reason is two-fold :
- Centering solutions based on knowledge of element heights should be deprecated now that we are adopting fluid and responsive layouts where widths (and hence heights) will vary greatly.
So to start lets throw out any idea of trying to center objects using
- CSS grew up a bit, got some irregularly supported pimples (The Flexible Box Module Draft
display : box), exfoliated for months with W3C scrub and became the incredibly good lookin CSS3 (with Flexible Box Module
display : flex)
margin : -n px and variants thereof and look at three ideas that work regardless of element heights.
Method 1 - Display as a Table Cell
If you grew up in the bad old days of table layouts, you will be very familiar with the fact that table cells have a useful ability to center inline elements vertically, by setting the
Of course now we're older and wiser and despise tables for displaying anything that isn't tabular, but we can make a div behave like a table cell and vertically align stuff using
display : table-cell .
Naturally loads cleaner than the extra table tags, but it still doesn't sit 100% well with me. It isn't really a table cell, it doesn't sit in a table and the only reason I am styling it as such is to take advantage of one behaviour and that is vertical alignment. Still, it is a method that works consistently across a wide range of browsers (old and new).
But what about a purer way? How about the purpose built CSS Flexible Box Layout Module which exposes css properties for alignment and justification.
The only trouble is which version to use due to irregular browser support.
Method 2 - Flexible Box Layout Module (2009 Draft)
Here we only use the bits we really need from the flexible box module. In other words, to say we're looking to use the flexible box module
display : box, we want a horizontal layout
box-orient : horizontal and we want everything aligned centrally.
box-align : center. With browser specific prefixes this becomes a bit more verbose, but you get the idea.
For uses of the draft beyond just vertical alignment, take a look at the W3C 2009 Draft
Its worth noting that you can use this version of the module with legacy browsers by including the flexie.js shim
Method 3 - Flexible Box Layout Module (CSS3)
Probably the best description of the CSS3 flexible box module can be found in the MDN documentation. Worth noting is the comment at the bottom of the document : Firefox supports only single-line flexbox. To activate flexbox support, the user has to change the about:config preference "layout.css.flexbox.enabled" to
Our implementation is similar to the Flexbox Draft solution in Method 2 except for property names which have changed with the specification... So again, we're saying "hey, using the box layout module, set this to row/horizontal and centrally align it".
At the time of writing this, this worked only with Chrome and Firefox (with the about:config preference changed mentioned above - which I doubt our users will have done).
Which method you choose should really be all about your target browser audience. If you're needing to reach everyone with the minimum amount of performance impact (i.e. without including shims etc), the old table-cell hack in Method 1 may actually be the best. If you're in the rare position of working for a future audience who use modern browsers, Methods 2&3 are where its at. To cover more bases, you could use Modernizr, create CSS rules that work with the "flexbox" class it will pop on all browsers that support it and use methods 1, or 2&3 accordingly.