FRANK'S
TUTORIALS

VERTICAL CENTERING IN CSS v. 2.0

For this tutorial you need a basic knowledge of HTML and CSS. If you do not have that, you should do a beginner's course at for example W3 Schools . That's a very decent site when it comes to accuracy and completeness, and an excellent site didactically speaking.

Centering vertically in CSS is not as difficult as it seems. There are six — intuitive and valid — techniques and two questions that determine which technique can or must be used. The methods are these:

  1. Line-height.
  2. Traditional table cell.
  3. Display: table(-cell).
  4. Absolute positioning.
  5. Sibling centralizer I.
  6. Sibling centralizer II.

There may be more working techniques, but all I have seen are non-intuitive, complicated variants of the techniques described here. The techniques will be explained later, but first the two questions:

  1. Which heights have been set in absolute measures? None, only that of the to center object, only that of the parent element, or of both?
  2. Is IE7 support wanted?

In case of the line-height technique, it would seem important whether the object is text or a series of inline elements that does or does not wrap. However, if a wrapping object is put inside a <span></span>, any problem resulting from that wrapping no longer occurs.

Further, it would seem important whether the to center object is an inline or a block element. However, by simply giving an element display:block, display;inline-block or display:inline, that characteristic can easily be changed.

The only limitation is that IE7 will apply display:inline-block only to inline, not to block elements.

OPTIONS TABLE

Which heights have been set in absolute measures?
None Only of the object Only of the parent Of both
      Line-height* Line-height*  
Traditional table Traditional table Traditional table Traditional table
  Absolute postioning   Absolute positioning
  Sibling centralizer I   Sibling centralizer I
Sibling centralizer II Sibling centralizer II Sibling centralizer II Sibling centralizer II
Display: table(-cell) Display: table(-cell) Display: table(-cell) Display: table(-cell)

*: A wrapping object must be put in a <span></span>.

1. Line-height

The line-height determines the vertical distance between text lines. This is achieved by positioning the text line halfway the line-height, a vertical centering in itself. If you give a container a line-height as high as the container height, text and inline elements inside that container are centered along the line-height as well. And thus vertically centered in the container.

See the live example . The vertical-align: middle that the live example has is redundant for most browsers, but smart phones and tablets may have proprietary browsers.

If you are going to enclose the text with a <p></p> rather than with a <span></span>, be sure to give that a margin-top: 0. In the other techniques that is not necessary.

IE7 has a line-height bug: in the code, there must be a space or a hard return between two of the inline elements (the object) or between the (last) element and the closing tag of the container. Otherwise, it doesn't work.

Finetuning is necessary in case the text has a different font size than 1em or the equivalent thereof, but can easily be done by adjusting the line height. The formula is:

height of the parent - 1em = font-size x line-height

However, the optical result depends on the font type, so further finetuning may be necessary. And note the inheritance principle of font-size: if the body element has a font-size: .8em, a <p> with a font-size: 1em is rendered as .8em.

2. Traditional table cell

This technique is the only possible one (of the intuitive techniques, anyway) if the object is text lines or inline elements that wrap, or a block element with an unknown height, and IE7 support is wanted (which it should be). As in the previous technique, you should cover for propietary browsers, by giving the table cell and the inline element(s) a vertical align: middle.

3. Display: table(-cell)

This property value perfectly mimics a traditional table cell, but is not supported by IE7. The principle is the same as well. However, here the container must get a vertical-align: middle, otherwise even the standards-compliant browsers position the object at the top. The live example you can find here .

You cannot center the object relative to the body element directly. You need an intermediate container for that, which acts as the table cell, with the body element acting as the table. So, the body gets display: table and the container display: table-cell. Also, all elements acting as table or table cell must get a width declaration. Natively, tables and table cells have zero width, and so do elements with a display: table(-cell).

4. Absolute positioning

This technique requires that the height of the object is set. If the object is to be centered relative to the body element, in the middle of the page, simply add the following CSS code to the object. However, if it must be centered inside a lower element than the body, that (parent) element must get a position:relative unless it already has a position:absolute of its own.

The principle is: move the object down so that its upper border is at half the height of the container, by means of top: 50%. Next, move it back up by means of a negative margin-top. The value of the negative margin-top must be: half the height of the object plus half of the total top and bottom borders and paddings. If this sounds peculiar, have a look at the following demonstration:

Open the live example of the next method, in which the horizontal centering is achieved through margin: 0 auto. That is perfect horizontal centering, isn't it? With absolute positioning, the object's exact same position is achieved with a negative margin-left of half its width plus half the total left and right borders and paddings. Just toggle between the two live examples and view the source code to see for yourself.

5. Sibling centralizer I

This technique is based on the principle that an element with a negative margin-bottom will pull the element below it up. If we give the upper (sibling) element a height of half the height of the (parent) container, and a negative margin-bottom of half the height of the element below it plus its borders and paddings, we get a perfect vertical centering of the lower element.

6. Sibling centralizer II

This technique is a more intuitive variant of the technique apparently created by Michal Czernow. It is based on the principle that two inline(-block) elements with a vertical-align: middle vertically center each other inside their common parent element.

Because inline elements are not susceptible to dimension declarations, we want to use display: inline-block. And because IE7 will only apply that to native inline elements, this technique does not work in that browser version.

If you want to center the object relative to the body element, that and the html element must get a height: 100%. This is because the sibling centralizer element must have that as well.


Change log
V. 2.0: Added Sibling centralizer II technique. Replaced the flowchart with the table in the text.


About
I am Frank Conijn, a web designer and author from Amsterdam, the Netherlands. At the moment, I am too busy with other web projects to be making websites for others, but I am available if you want to hire me for problem solving or advice. Just mail me at f.conijn@conijnbotFoolconsultancy.com.

Was this article helpful and do you have any Google account? A Google recommendation of my business, by means of simply clicking this button, is appreciated:

For general comments on and suggestions for this article, mail met at the above address. For free help with minor problems, post your question on one of these web design forums (pop-up).