• Horizontal and Vertical Centering Using CSS: A Beginner’s Guide

  • By: Jarod Taylor | Category: HTML & CSS
  • There comes a time in every web designer's life, when you're trying to center an HTML element and it's failing miserably. You're ready to pull the plug on CSS, revert back to tables, and use deprecated tags and attributes like: <center>, align, and valign. In this tutorial we're going to shed some light on the subject, and hopefully help demystify the process of centering HTML elements using CSS.

    Introduction

    Back in 'nam, when we wanted to center an element horizontally, we used the align attribute or the deprecated <center> tag. In order to align elements vertically, we would use the valign attribute. Those days are long and gone. We are using much cleaner and semantic methods of marking up our HTML documents now. We're using that beautiful acronym known as CSS.

    The first bulk of the tutorial is going to be discussing methods of centering elements horizontally. While horizontal alignment tends to be an easier task to accomplish (in comparison to vertically aligning HTML elements), at times, it can still challenge even the most seasoned front end developer.

    After turning your brain to mush and playing with horizontal alignment, we'll dive into the different options used today in vertically aligning HTML elements.

    Tutorial Navigation
    1. Inline vs. Block
    2. Horizontally centering inline-level elements
    3. Horizontally centering block-level elements
    4. Horizontally centering block-level elements with an unknown width
    5. Horizontally centering absolute positioned elements
    6. Getting started with vertical alignment
    7. Vertically aligning inline elements with inline elements
    8. Vertically center an element using absolute positioning
    9. Vertically center an element using a "Shimmy Float"
    10. Vertically center an element with and unknown height
    11. Vertically and horizontally center an element using a table container

    Inline vs. Block

    In order to fully understand and maximize the abilities of CSS, one must first understand the difference between block-level and inline-level elements. Rather than regurgitate what has been explained numerous times before, I'm going to briefly describe the difference between a block-level element and an inline-element.

    Block Elements

    Block-level elements are treated as rectangular (block) objects, which will take up 100% of the width available (unless its given a specific width declaration), and will insert a line break before and after it. Block elements can have margins, width, and height settings.

    Block elements include common tags such as:

    • <div>
    • <p>
    • <h1>, <h2>, <h3>, <h4>, <h5>, and <h6>
    • <ul>, <ol>, <dl>
    • <li>, <dd>, <dt>
    • <table>
    • <form>

    While this isn't a complete list of block elements, it gives you and idea of some common elements that are block-level. For a more comprehensive list of block-level elements try the trustee Wikipedia.

    Noobnote:

    While block-level elements automatically take up 100% of their parent's width (if a width has not been declared), a table element will not stretch the width of its parent, it will only take up as much width as it needs; similar to an inline-level element. Take a look at this example.

    Inline Elements

    Inline-level elements are treated as part of the flow of document text, so it will not insert a line break before and after it, and only takes up the width it requires. Inline elements cannot have margins, width, or height settings.

    Inline elements include common tags such as:

    • <a>
    • <span>
    • <img>
    • <em>
    • <strong>
    • <input>
    • <abbr>

    While this isn't a complete list of inline elements, it gives you and idea of some common elements that are inline-level. For a more comprehensive list of inline elements try the trustee Wikipedia.

    Demo
    tutorial image
    Can block-level elements be inline-level elements?

    Just because an element's natural state is inline or block doesn't mean they have to be used that way. That's what the display: value property is for.

    div {
         display: inline;
    }
    
    span {
         display: block;
    }
    

    We just changed the block-level <div> to an inline-level element by declaring display: inline, and we changed the inline-level element <span> to a block-level element by declaring display: block.

    More Block vs. Inline Resources
    So, what are you trying to say Jarod?

    The difference between a block-level element and an inline-level element can pretty much be summed up in one sentence: block-level elements begin on a new line and create a line break afterward, and inline-level elements do not.

    So, what's this have to do with centering HTML elements? How to center an element, using CSS, depends entirely on whether or not it is an inline element or a block element. Different methods of centering are used for each type of element. That's what we'll explore next.

    Horizontally centering Inline-Level elements

    Chances are, you've already centered text before using the text-align property, but this property, in fact, will center all inline-level elements. The way this works is by giving the inline-level element's parent block-level element the declaration of text-align: center.

    Noobnote:

    For the sake of brevity, during the rest of this tutorial, I will refer to block-level elements as block elements and inline-level elements as inline elements.

    Let's look at some examples here. We need a block element containing an inline element (eg. an anchor inside of a div). Let's use a couple different inline elements inside separate block elements. We'll use a div as the parent block element and a <span>, <a> and an <img> for our inline elements.

    HTML
    &lt;div&gt;
    	&lt;span&gt;I'm a pretty inline-level &lt;em&gt;span&lt;/em&gt; tag&lt;/span&gt;
    &lt;/div&gt;
    
    &lt;div&gt;
    	&lt;a href=&quot;#&quot;&gt;I'm a pretty inline-level &lt;em&gt;anchor&lt;/em&gt; tag&lt;/a&gt;
    &lt;/div&gt;
    
    &lt;div&gt;
        &lt;img src=&quot;images/puzzlepiece.png&quot; alt=&quot;I'm a pretty inline level image tag&quot; /&gt;
    &lt;/div&gt;
    

    We have 3 separate block elements containing 1 inline element each. Now we need to add some CSS to demonstrate how to center an inline element.

    First thing we need to do is give our parent block element (div) a style declaration of text-align: center.

    CSS
    div {
    	text-align: center;
    	background: #efefef;
    	margin-bottom: 10px;
    }
    
    a, img, span {
    	border: 1px solid #3d3d3d;	
    }
    

    The reason our div is getting text-align: center is because the text-align property doesn't actually effect the alignment of the element itself (in this case: the div); it effects the alignment of its inline-level contents.

    Noobnote:

    If we put text-align: center on one of the inline elements, nothing would happen. Technically, it would be centering the content inside the inline element, but the inline element's width is only as wide as it needs to be, so you're not going to see a difference.

    The other styles we added were for display purposes. They're not required for this demonstration, but it makes it a little easier to see what element is what. This is what we get with these styles applied to our demo.

    As you can see, our block element divs have a light gray background and take up 100% of its parent element's width (in our case the <body>'s width). The inline-level content is centered inside of each block element. I've applied a border to our inline elements to show where they begin and end.

    What if we change our inline-level elements to block-level elements?

    Let's give it a try. First, we need to remove our divs from the document.

    HTML
    &lt;span&gt;I'm some inline text inside of an inline-level &lt;em&gt;span&lt;/em&gt; that's been changed with &lt;code&gt;display: block&lt;/code&gt;&lt;/span&gt;
    
    &lt;a href=&quot;#&quot;&gt;I'm some inline text inside of an inline-level &lt;em&gt;anchor&lt;/em&gt; that's been changed with &lt;code&gt;display: block&lt;/code&gt;&lt;/a&gt;
    
    &lt;img src=&quot;images/puzzlepiece.png&quot; alt=&quot;I'm a pretty inline level image turned block&quot; /&gt;
    

    Now we've removed all block elements from our HTML and are left with 3 inline elements.

    What we need to do next is move all of our div styles to our a, img, span styles.

    CSS
    a, img, span {
    	text-align: center;
    	background: #efefef;
    	margin-bottom: 10px;
    	border: 1px solid #3d3d3d;
    	display: block;
    }
    

    We've moved our div styles to our inline element styles, and also changed their display property to display: block.

    Noobnote:

    When you change an element's natural display property, using CSS (eg. declaring display: block; on a span element), you're technically only telling the browser to treat it as a block-level element. As far as the HTML is concerned, it is still an inline-element.

    Take a look at what we have with our new changes. You'll see that our once inline-level elements are now being treated as block elements. Remember though, we aren't centering the actual <span>, <a>, and <img> elements; we're centering their content. In the cases of the <span> and <a> elements, the content is text. Text is naturally an inline-level element, and cannot be changed, therefore they're being centered within their respective block-level containers (<span> and <a>).

    Why didn't the <img> center with the other elements?

    You might be asking, "why didn't the image center?". This can be confusing at first, but keep in mind, that the image tag doesn't contain anything other than itself. Remember: we aren't centering the element with text-align: center, we're centering its contents.

    Noobnote:

    The text-align property is an inherited value. This means, if you declare body { text-align: center; }, all the body element's children that are inline-level will also be centered, unless you declare it specifically, otherwise.

    Horizontally Centering Block-Level Elements

    As opposed to centering inline elements, centering block elements is done by actually applying CSS rules to the element you're actually wanting centered. This is done by using the margin property. By giving our block element a left and right margin value of auto, it's essentially creating equal left and right margins, therefore centering the element.

    Let's look back at our last demo, and make a few changes to our newly converted block-level elements. Let's start with just centering the span element.
    I've highlighted the additions to our CSS.

    a, img, span {
    	text-align: center;
    	background: #efefef;
    	margin-bottom: 10px;
    	border: 1px solid #3d3d3d;
    	display: block;
    }
    
    span {
    	margin-right: auto;
    	margin-left: auto;
    }
    

    If you take a look at our page, you'll see nothing has changed. This is because our span element doesn't have a width declaration. When a block-level element doesn't have a width declared, it's default value is auto. If a block element has the width value of auto, it will take up 100% of the width of its parent element. In this case, our span element's parent is the body element.

    Noobnote:

    In our newly added styles for our span element, you'll notice that I have two separate style declarations for the margin-right and margin-left properties. It's common practice to use CSS shorthand, to make our stylesheets more efficient. Rather than using two separate style declarations like we did above, we could do it this way: margin: 0 auto 10px auto, or even shorter because our left and right values are the same, margin: 0 auto 10px.

    Let's give our span element a width and change its margins to use CSS shorthand.

    span {
    	margin: 0 auto 10px;
    	width: 800px;
    }
    

    You'll now see our span element is centered inside the browser.

    Let's go ahead and center our anchor element now as well.

    a, img, span {
    	text-align: center;
    	background: #efefef;
    	margin-bottom: 10px;
    	border: 1px solid #3d3d3d;
    	display: block;
    }
    
    span {
    	margin: 0 auto 10px;
    	width: 800px;
    }
    
    a {
    	margin: 0 auto 10px;
    	width: 70%;
    }
    

    The only difference with our a element styles and the span element is the width value was declared using a percentage instead of a pixel dimension. If you take a look at our demo you'll see the anchor element is now centered.

    Centering our img element is little different. Images have what are called intrinsic dimensions, basically meaning that the browser already knows the dimensions of the image, therefore, it doesn't need a width explicitly declared. All we need to do is add the auto margins to our img styles.

    img {
    	margin: 0 auto 10px;
    }
    

    You'll now see our image is centered.

    Noobnote:

    Just because we don't have to declare a width for our img element, it still needs to be a block-level element for it to accept the margin property values. You can't just put auto margins on an image and expect it to center. You have to first convert it to a block element with display: block.

    That's pretty much it! Now keep in mind, in order for Internet Explorer 6 and 7 to handle the auto margins correctly, you must be running in standards compliance mode and not in Quirks Mode.

    This is all pretty simple and easy to understand, but what happens when we don't know the width of our block-level element we want to center? This is what we'll be tackling next.

    Horizontally Centering Block-Level Elements with an Unknown Width

    There are rare occasions when you're wanting to center a block-level element, where the width of the element is unknown. This is especially more common when you're receiving content dynamically.

    Let's create 3 <p> elements as our block-level elements. We'll put a little text in each, incrementally, making each one longer than the one before.

    HTML
    &lt;p&gt;I'm a block-level paragraph taking up as much width as I can.&lt;/p&gt;
    &lt;p&gt;I'm a block-level paragraph taking up as much width as I can. I'm a little bit longer than the one above.&lt;/p&gt;
    &lt;p&gt;I'm a block-level paragraph taking up as much width as I can. I'm a little bit longer than the one above, but much longer than the first one.&lt;/p&gt;
    

    Nothing exciting here, just some paragraph tags with some basic text as its content. What we need to do is give our p elements some styles to make it easier to identify each of them. Let's start with some basic styles.

    CSS
    p {
    	background: #ccc;
    	padding: 5px;
    	border: 1px solid #000;
    }
    

    It's pretty self explanatory what we've done here. We gave each of our p elements a background color and border to help distinguish each of them. We also gave each of them a padding to give the text some space.

    If you remember, from the previous section, an img element does not need to have a width declared in order for margin: 0 auto to work. It only needs to be converted to a block-level element so it will be able to have margin property values. I also explained briefly, in the block vs. inline section of this tutorial, that the table element was the only block-level element that did not take up 100% of its parent element width. It, much like the inline-level element, will only take up as much width as it needs. The reason I bring this up is because CSS has another property worth looking at, display: table. If we declare our display property value as table on our p elements, they will be treated as a block-level table element.

    This means two things:

    1. The table element will only take up as much width as it needs. So there's no need to declare a width for it.
    2. It's still treated as a block-level element, therefore it will still render the margin property.

    Let's go ahead and add some styles to our CSS. I've highlighted the changes.

    p {
    	background: #ccc;
    	padding: 5px;
    	border: 1px solid #000;
    	display: table;
    	margin: 10px auto;
    }
    

    We did a couple things here. We first added the display: table declaration to get our p elements to render as table elements. We also gave our elements some breathing room by giving it a 10px bottom and top margin, while also centering them using the auto value for our right and left margins. Take a look at what we get.

    Depending on the browser you're using, you will probably get mixed results. The majority of your modern browsers support the display: table property, while a handful of others do not (*cough* Internet Explorer *cough*). It's true, our favorite web browser has chosen to rain on our parade, yet again. Unfortunately, IE7 and below do not support this display value. On a positive note, Internet Explorer 8 does. But, unfortunately, we'll be developing for IE7 for years to come, so this is a big "unfortunately". Fortunately, and I use that term loosely, there is a workaround to make this work in Internet Explorer 7 and 6.

    Getting IE6 and IE7 to behave

    Because IE7 and below do not support display: table, we need to do some dirty work. We will try and make this as clean as possible, but unfortunately, due to the lack of CSS rendering of these 2 browsers, we'll have to use some solecistic arbitrary markup.

    First thing's first, what can we use to get our p elements to only be as wide as they need to be, like table elements and inline-level elements? Well, just like we can convert inline elements to block elements, we can convert block elements to inline elements with display: inline and create a container to hold the p elements and give it a text-align value of center. Let's start with the additional HTML. I've highlighted the changes.

    HTML
    &lt;div id=&quot;ie-container&quot;&gt;
        &lt;p&gt;I'm a block-level paragraph taking up as much width as I can. I do not have a width declaration.&lt;/p&gt;
        &lt;p&gt;I'm a block-level paragraph taking up as much width as I can. I'm a little bit longer than the one above.  I too, do not have a width declaration.&lt;/p&gt;
        &lt;p&gt;I'm a block-level paragraph taking up as much width as I can. I'm a little bit longer than the one above, but much longer than the first one.  I do not have a width declaration.&lt;/p&gt;
    &lt;/div&gt;
    

    We've wrapped our p elements in a block-level div, so that we can give it a style declaration of text-align: center in order to center all inline-level elements inside of it.

    We need to add some new styles to our CSS in order to get IE6/IE7 to pretend to be good browser. Let's put these styles below our other styles inside conditional comments.

    CSS
    &lt;!--[if lte IE 7]&gt;
    &lt;style type=&quot;text/css&quot;&gt;
    #ie-container {
    	text-align: center;
    }
    
    p {
    	display: inline;
    }
    &lt;/style&gt;
    &lt;![endif]--&gt;
    

    Let's take a look at our page in Internet Explorer now. It's getting closer, but there are some things to work on. First of all, because our p elements are now being treated as inline elements, we need to put in <br /> tags after each p element.

    &lt;div id=&quot;ie-container&quot;&gt;
        &lt;p&gt;I'm a block-level paragraph taking up as much width as I can. I do not have a &lt;code&gt;width&lt;/code&gt; declaration.&lt;/p&gt;&lt;br /&gt;
        &lt;p&gt;I'm a block-level paragraph taking up as much width as I can. I'm a little bit longer than the one above.  I too, do not have a &lt;code&gt;width&lt;/code&gt; declaration.&lt;/p&gt;&lt;br /&gt;
        &lt;p&gt;I'm a block-level paragraph taking up as much width as I can. I'm a little bit longer than the one above, but much longer than the first one.  I do not have a &lt;code&gt;width&lt;/code&gt; declaration.&lt;/p&gt;&lt;br /&gt;
    &lt;/div&gt;
    

    Now that we've added break tags after our paragraph elements, it's rendering much better in IE, but there's still some work needed. You'll notice something funky is happening with our p elements. They're crowding each other and missing parts of their border. This is caused by IE's proprietary pain in the ass, hasLayout. Because we're putting our styles inside of conditional comments, I'm choosing to use zoom: 1 to gain hasLayout in IE.

    &lt;!--[if lte IE 7]&gt;
    &lt;style type=&quot;text/css&quot;&gt;
    #ie-container {
    	text-align: center;
    }
    
    p {
    	display: inline;
    	zoom: 1;
    }
    &lt;/style&gt;
    &lt;![endif]--&gt;
    

    Voila! If you take a look at our page in IE6/IE7 now, you'll see our elements centering and handling just like they should.

    Now, for the cleanup. Yes, we now need to do a little cleanup. If you were to look at our page in a "good" browser, like Firefox, you'll see that the <br /> tags have added more space than needed between our paragraph elements. It's a quick and easy way to cleanup. We need to just display the <br /> tags to IE7 and below, so we'll set our CSS to display: none on br elements and then display: inline to IE7 and below.

    &lt;style type=&quot;text/css&quot;&gt;
    p {
    	background: #ccc;
    	padding: 5px;
    	border: 1px solid #000;
    	display: table;
    	margin: 10px auto;
    }
    
    #ie-container br {
    	display: none;	
    }
    &lt;/style&gt;
    
    &lt;!--[if lte IE 7]&gt;
    &lt;style type=&quot;text/css&quot;&gt;
    #ie-container {
    	text-align: center;
    }
    
    p {
    	display: inline;
    	zoom: 1;
    }
    
    #ie-container br {
    	display: inline;	
    }
    
    &lt;/style&gt;
    &lt;![endif]--&gt;
    

    We now have a a page demonstrating how to center block-level elements without declaring a width.

    Horizontally Centering Absolute Positioned Elements

    Centering an element that has position: absolute declared is quite simple if there's a width declared.

    Let's create a simple div with a fixed width, absolute positioning, and some basic styles for appearance. We'll start with the HTML.

    HTML
    &lt;div&gt;I'm a horizontally centered div that's absolutely positioned in the browser.&lt;/div&gt;
    
    CSS
    div{
    	width: 600px;
    	position: absolute;
    	left: 50%;
    	margin-left: -300px;
    	background: #CCC;	
    }
    

    What we've done is given our div element a width of 600px and a position: absolute declaration. We gave it a background color just to show the 600px element. What's important here is the left and margin-left values. We've set our left value to 50% which moved our element over 50% from the left. We then take half of the element size and put a negative margin-left value equal to that. In our case, half of 600px is 300px. Take a look at what it renders.

    Getting Started with Vertical Alignment

    Unlike horizontal centering, vertical centering can be a nightmare. There a few different methods of vertically centering content in HTML, but all methods have their pros, cons, and browser inconsistencies. We're going to touch base on the most common ways of achieving vertical centering.

    Noobnote:

    Looking to just vertically align one line of text? Try this simple method:

    Give your block element a height and line-height equal to one another. This will vertically align the text in its container. Beware, if the line wraps, it will fail miserably. Use this with caution. Here's an example.

    Vertically Aligning Inline Elements with Inline Elements

    Taking inline elements and aligning them is quite easy with the CSS vertical-align property. Much like the old school table days, vertical-align accepts a number of values. Chris Coyier does a pretty good job explaining the differences in the values here, so rather than repeating what's been said before, I'm just going to briefly run an example by you.

    Take some inline level elements and apply vertical-align: middle to them and you'll see a little magic.

    HTML
    &lt;span&gt;This is some text with an image dropped inside of it &lt;img src=&quot;http://www.noobcube.com/wp-content/uploads/demos/082809-centeringdemystified/images/puzzlepiece.png&quot; alt=&quot;&quot; /&gt; inline and centered in the middle&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;
    
    &lt;img src=&quot;images/puzzlepiece.png&quot; alt=&quot;I'm a pretty inline level image tag&quot; /&gt;
    &lt;a href=&quot;#&quot;&gt;Important link with an icon&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;
    
    &lt;span class=&quot;sixty&quot;&gt;WORD&lt;/span&gt;
    &lt;span class=&quot;thirty&quot;&gt;WORD&lt;/span&gt;
    
    CSS
    img, span, a {
    	vertical-align: middle;
    	border: 1px solid #000;
    }
    
    .sixty { font: bold 60px Arial, Helvetica, sans-serif;}
    .thirty { font: bold 30px Arial, Helvetica, sans-serif;}
    

    I added some basic styles to better distinguish the different elements, but the important property here is the vertical-align style declaration. Take a look at our example.

    Vertically Center an Element Using Absolute Positioning

    Much like we did to center an absolute positioned element horizontally, we can do to center it vertically, as well. Let's take a look at our example from the Horizontally centering absolute positioned elements section of this tutorial.

    Let's give it a height of 600px as well as a top value of 50%. Just like we did to horizontally center it, we'll give the element a negative margin-top value.

    div{
    	width: 600px;
    	height: 600px;
    	position: absolute;
    	left: 50%;
    	top: 50%;
    	margin: -300px 0 0 -300px;
    	background: #CCC;	
    }
    

    As expected, we have a vertically and horizontally centered element.

    Vertically Center an Element Using a "Shimmy Float"

    Okay, so "shimmy float" is a silly name I call this technique, I learned from Douglas Heriot's tutorial. In carpentry, small pieces of wood are used as shims to align gaps between larger pieces of wood. When using the "shimmy float" technique, we're going to use an arbitrary div as sort of a shim to center the content below it.

    Much like the position: absolute method, this technique depends on its centered element having a fixed height. Let's start with a container div and some basic styles.

    HTML
    &lt;div id=&quot;container&quot;&gt;
    Hi, I'm a div. I want to be vertically centered.
    &lt;/div&gt;
    
    CSS
    #container {
    	height: 500px;	
    	background: #3d3d3d;
    	color: #efefef;
    }
    

    Alright, we have a starting point.

    Now we need to create an empty div above our container div to act as our shim.

    &lt;div id=&quot;shim&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;container&quot;&gt;
    Hi, I'm a div. I want to be vertically centered.
    &lt;/div&gt;
    

    This div needs to float: left and have a height of 50%. There's something that needs to be done before our shim element will understand height: 50%. We need to give our html and body element a height of 100%.

    At the top of our CSS we need to add the following styles:

    html, body {
    	height: 100%;
    	padding: 0;
    	margin: 0;
    }
    

    This will allow us to give any element in our document a height using a percentage rather than a fixed pixel dimension. We also zeroed out the body's margin and padding properties, or else we'd end up with a vertical scrollbar in our browser.

    Now for the shim styles:

    #shim {
    	float: left; 
    	height: 50%; 
    	margin-bottom: -250px; 
    	width: 1%;
    }
    

    We've floated our shim left and given it its height of 50%. We also gave it its negative bottom margin of 250px which is half the height of the container div we're trying to center. The width: 1% is necessary for IE to render our shim, otherwise it acts as if it doesn't exist.

    That's it! Take a look at the example, and you'll see the container div is vertically centered in the browser.

    Vertically Center an Element with an Unknown Height

    Yes, we're breaking out display: table again, and this time bringing its counterpart display: table-cell. Let's jump right in and get our HTML done first.

    &lt;div id=&quot;table&quot;&gt;
    	&lt;div id=&quot;cell&quot;&gt;
    		&lt;div id=&quot;content&quot;&gt;
    			&lt;p&gt;Hi, I'm some content&lt;/p&gt;
    		&lt;/div&gt;
    	&lt;/div&gt;
    &lt;/div&gt;
    

    We have ourselves a small bowl of div soup here, but it's necessary in order for this to work properly. If you remember, from the beginning of this tutorial, when using display: table, we can use the CSS property vertical-align. That's exactly what we're going to do with the <div id="cell"> element.

    First thing's first, our <div id="table"> needs to be givin' 100% height so that our <div id="cell"> will vertically align to the middle of the browser window. Remember, in order to give our element's a height of 100%, we need to give our html and body elements 100% height. In this example, we're going to horizontally center the <div id="content"> element inside the <div id="cell"> element, therefore we need to give our <div id="table"> element 100% width too, so that it stretches the width of the browser.

    Here's what we end up with:

    CSS
    html, body {
    	height: 100%;
    	padding: 0;
    	margin: 0;
    }
    
    #table {
    	display: table; 
    	height: 100%;
    	width: 100%;
    }
    
    #cell {
    	display: table-cell; 
    	vertical-align: middle;
    }
    
    #content {
    	width: 960px;
    	background: #3d3d3d;
    	margin: 0 auto;
    }
    

    Take a look at our example. Once again, if you're viewing this in IE7 or below, you're not seeing what you want to be seeing right now. As we already discussed, IE7 and below do not support display: table, nor display: table-cell.

    Getting IE7 and IE6 to Behave

    Guess what we need to create again? Yep, we need a div which we'll call "ie-container", and add some conditional styles to help it do what it needs to do.

    I've highlighted the addition to our HTML.

    HTML
    &lt;div id=&quot;table&quot;&gt;
    	&lt;div id=&quot;cell&quot;&gt;
    		&lt;div id=&quot;ie-container&quot;&gt;
    			&lt;div id=&quot;content&quot;&gt;
    				&lt;p&gt;This is content&lt;/p&gt;             
    			&lt;/div&gt;
    		&lt;/div&gt;
    	&lt;/div&gt;
    &lt;/div&gt;
    

    Our new div (ie-container) is going to need some styles, but again, this is only needed for IE7 or below so we'll use some conditional comments. Put this below your </style> tag.

    &lt;!--[if lte IE 7]&gt;
    &lt;style type=&quot;text/css&quot;&gt;
    #ie-container {
    	position: relative;
    	float: left;
    	top: 50%	
    }
    
    #content{
    	top: -50%; 
    	position: relative;
    }
    &lt;/style&gt;
    &lt;![endif]--&gt;
    

    We've given our new ie-container div a relative position and a top margin of 50%, moving it and its contents down 50%. We then exploit an IE bug that goes back to version 5, by giving our <div id="content"> element a relative positioning and giving it a negative top margin equal to its containing elements positive top margin (-50%). All other browsers would just move the content right back up to where it was before, but IE7 and below will only move it up half way, therefore, centering it! It's a shame we have to go through these lengths to get IE to cooperate, but it's nice to exploit its flaws from time to time.

    Let's take a look at our page in IE now. You should now see our content vertically centered without declaring a height on it. To test it, simply put more paragraphs inside the content div and you'll see.

    Vertically and Horizontally Center an Element Using a Table Container

    I know in today's web design world, we cringe at the thought of using tables. The reality is, CSS is here to make our lives easier, not to completely replace HTML tables. So, let's open our minds a little bit and let our old friend in.

    HTML
    &lt;table&gt;
    	&lt;tr&gt;&lt;td&gt;
    		&lt;div&gt;
    			Hi, I'm some content. ASL?	
    		&lt;/div&gt;
    	&lt;/td&gt;&lt;/tr&gt;
    &lt;/table&gt;
    

    All we have here is a classic table element containing our <div id="container">. Now let's look at the flexibility we have with this method.

    Let's vertically center our container div

    This is done quite easily without any need for conditional hacks for IE. This will work in ALL BROWSERS. First thing we need to do is give our html and body element a 100% height so that our table will be able to stretch the height of our browser window. Let's also go ahead and reset the page's padding and margins to zero. Then we'll use vertical-align: middle on our table with a height of 100% height. This will now align the table's contents (<div id="container">) in the middle of the browser. We'll give our div container some styles to make it a bit prettier.

    CSS
    * {
    	padding: 0;
    	margin: 0;
    }
    
    html, body {
    	height: 100%;	
    }
    
    table {
    	vertical-align: middle;
    	height: 100%;
    }
    
    #container {
    	background: #CCC;
    	border: 1px solid #000;
    }
    

    Let's take a look at what we have so far. Not bad, we have a small little div vertically centered in the browser, and it's working in IE too. Now, here comes the fun stuff. What do we want to do? Do we want a fixed height and width div vertically and horizontally centered in our browser? Or, should we have it vertically and horizontally center without giving it a width OR height? Oh.. the possibilities.

    Vertically and Horizontally Centered (Fixed Height & Width)

    Alright, let's say we want our div container to have a fixed height and width, be centered horizontally and vertically in the browser, and have an overflow: auto if the content grows longer than the height. First thing's first, we need to give our table element a width of 100% to stretch the width of the browser. If you remember, the table element is the only block-level element that doesn't take up 100% of its containing element width. It only takes up as much as it needs. In order for our fixed width div container to center with margin: 0 auto, we need its parent element (table) to stretch the width of the browser. I've highlighted the CSS additions.

    * {
    	padding: 0;
    	margin: 0;
    }
    
    html, body {
    	height: 100%;	
    }
    
    table {
    	vertical-align: middle;
    	height: 100%;
    	width: 100%;
    }
    #container {
    	background: #CCC;
    	border: 1px solid #000;
    	height: 600px;
    	width: 800px;
    	margin: 0 auto;
    	overflow: auto;
    }
    

    We gave our table element a width of 100%. We gave our div container a width of 800px and centered it using margin: 0 auto. We also gave our container div a height of 600px, with an overflow value of auto. This will cause a vertical scrollbar, should the content grow more than 600px. Let's just add some more content to our div to force a vertical scrollbar and see what we get.

    Vertically and Horizontally Centered (Unknown Width & Height)

    But, what if we don't know the width OR height of the content? You'd think this would be impossible, but it's actually a LOT easier than you think. First thing we need to do is remove all the styles we just added to create the fixed width and height centered div. Remember in the beginning of the tutorial when we talked about table elements and how they're the only block-level element that doesn't stretch 100% the width of its containing element? What this means is, our table can understand margin: 0 auto without any width declaration.

    * {
    	padding: 0;
    	margin: 0;
    }
    
    html, body {
    	height: 100%;	
    }
    
    table {
    	vertical-align: middle;
    	height: 100%;
    	margin: 0 auto;
    }
    
    #container {
    	background: #CCC;
    	border: 1px solid #000;
    }
    

    Take a look for yourself. How easy was that? The best part is, it works in ALL your major browsers, including IE6.

    So, it's up to you. Are you going to throw tables in the trash completely?

    Final Thoughts

    As you can see there a number of ways to center elements in HTML, both vertically, and horizontally. Which one you choose to use will depend entirely on what it is you're trying to achieve. Are there any methods that I missed, that you use? Let me know and I'll add them to the tutorial, giving you full credit.

    Thanks again for reading!