Vertical Centering with CSS

Centering Vertically:

There are a few ways to center vertically. In terms of block level elements, the methods are quirky. Inline elements are much simpler to center:

If you know the height of your containing div, and the height of your inner centered div,  or, if you the height of your inner div does not matter, then vertical aligning is simple.  However, if you are vertically centering anything that is variable, such as text, vertical centering is more complex and require hacks.

Note: If you are looking for support for the css property vertical-align, check out the table of CSS properties, values and browser support.

The HTML used in our examples:

<div id="containingBlock">
  <div>
     <p>This sentence will change in each example</p>
</div> </div>

Note: I will post an entry on vertical centering of text soon

Mathematical Method for known heights:

When you know the height of the containing element, and the height of the element being vertically centered, simply use math to figure out the height of the margins on the inner element.

#containingBlock {display: block; height: 200px;}
#containingBlock div {height:50px; margin: 75px 0;}

The green outlined div is vertically centered in all browsers.

As is evident in the above example, this method really only works for images or other media when you know the exact height of your content. This method should not be used for containing text as a developer really never knows how much text will be contained in the box in the end, and the font size: users should be allowed to increase font size.  In our example, the text does not take up the height alloted to the paragraph, so it is not vertically centered, but the containing div (i made the background grey) is centered..

Block level vertical centering via the table display method:

Vertically centering block level elements should be simple simply by using display: table; and vertical-align: middle.  Unfortunately, IE6 and IE7 do not understand the value of table and table-cell as values of the display property.

The CSS for CSS compliant browsers:

#containingBlock {display: table; height: 200px; position: relative; overflow: hidden;}
#containingBlock div {display: table-cell; vertical-align: middle;}

Rendering of the above code: (borders have been added so you can see the effect, and div id is actually unique) has the anticipated look in Firefox, Safari and other CSS compliant browsers, but not in IE, including IE7.:

Works in FireFox and Opera

The CSS for IE6 and IE7:

#containingBlock {height: 200px; position: relative; overflow: hidden;}
#containingBlock div { position: absolute; top: 50%;}
#containingBlock div p {position: relative; top: -50%;}

Rendering of the above code: (borders have been added so you can see the effect):

Works in IE6 and IE7

The concept is that the outer content which is relatively positioned and has a defined height contains an absolutely positioned div that starts 50% from the top of the container div.  The absolutely positioned div, in turn, contains a relatively positioned element that has as it’s middle the top of the absolutely positioned div.  Look at the colors in IE, and if the above sentence didn’t make sense, it will.

Vertical Alignment Table Display Hack


#containingBlock {display:table; height: 200px; position: relative; overflow: hidden; }
#containingBlock div {*position: absolute; top: 50%; display: table-cell; vertical-align: middle;}
#containingBlock p {*position: relative; top: -50%;}

Works in IE6 and IE7, Firefox, Safari, etc., but doesn’t validate

Vertically Centering Fluid elements within a page (useless, except for useless splash pages):


html, body, #containingBlock {height: 100%; position:relative; } 			
#containingBlock div {height: 50%; position: absolute; top: 25%; } 		
This entry was posted in CSS (including hacks), Web Development. Bookmark the permalink.

6 Responses to Vertical Centering with CSS

  1. nripendra says:

    Hi, thanks for this article, I was having hard time for this particular issue.

    I’ve changed your code so that it will work as well as validate too..

    I’m posting it:

    first for standard browsers which understands display:table

    #containingBlock
    {
    display:table;
    width:200px;
    height: 200px;
    overflow: hidden;
    text-align:center
    }
    #containingBlock div
    {
    display: table-cell;
    vertical-align: middle;
    }

    now for IE, the trick is to use IE conditional comments, for example:

    #containingBlock
    {
    position: relative;
    }
    #containingBlock div
    {
    position: absolute;
    top: 50%;
    left:50%; /*for centering horizontally*/
    }
    #containingBlock p
    {
    position: relative;
    top: -50%;
    left:-50%;/*for centering horizontally*/
    }

    the markup will be same as in your example…
    now the css will validate and also works differently for other browsers and IE

  2. nripendra says:

    Posting once again…, with no html tags…

    Hi,
    thanks for this article, I was having hard time for this particular issue.

    I’ve changed your code so that it will work as well as validate too..

    I’m posting it:

    first for standard browsers which understands display:table

    <style&gt
    #containingBlock
    {
    display:table;
    width:200px;
    height: 200px;
    overflow: hidden;
    text-align:center
    }
    #containingBlock div
    {
    display: table-cell;
    vertical-align: middle;
    }
    </style&gt
    now for IE, the trick is to use IE conditional comments, for example:
    <!–[if IE]&gt
    <style&gt
    #containingBlock
    {
    position: relative;
    }
    #containingBlock div
    {
    position: absolute;
    top: 50%;
    left:50%; /*for centering horizontally*/
    }
    #containingBlock p
    {
    position: relative;
    top: -50%;
    left:-50%;/*for centering horizontally*/
    }
    <!-[end if]–&gt
    the markup will be same as in your example…
    now the css will validate and also works differently for other browsers and IE

  3. dan says:

    Hi,
    really good.
    In fact, I was looking for a pure HTML+CSS code (NO javascript) which was able to switch (with a button or anchor, or …) a DIV to visible/invisible (or block/none by using display). I know how to do in JS. But I would like to find same thing in pure HTML/CSS
    If possible…
    Any help would be very kind of you
    (sorry for bad english, I am french)
    Thanks by advance
    Dan

  4. estellevw says:

    Bonjour Dan-

    If an element is within another element, you can use the :hover pseudo-class on the parent to change the display on the child. Hover, this only works on “hover”, and will be hidden when the mouse is no longer hovering over the parent (or child).

    the issue with this, though, is that older IE versions only support the :hover pseudo class on link elements. And, display: none; is not accessible. To fix the accessibility, change the position instead of the display (so position it off the page). To fix the IE not understanding hover except for links, you can either encompass your visible/invisible in a link, or use javascript for the older browsers

  5. Man, centering and center-aligning has become so involved since the early days of HTML (I started way back when before CSS and XML were even a twinkle in some developer’s eye). Thanks for this article. P.S. Hopefully we won’t have to worry about coddling IE6 for much longer.

  6. Matt says:

    Even in 2011 these techniques are still really useful – thanks 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *