It's always good when you learn something that you already knew isn't it?
I know that probably doesn't quite make sense but what I mean is that quite often you know how things work but it's how they are applied that can make all the difference. This is the beauty with CSS where you can always be surprised at the different ways the same layout can be achieved. This happened to me the other week when I noticed a different way that a site had been centered using simple techniques already known to us all. Indeed, many of you may already have used this method but it seems to have escaped my attention until now.
The Old Way
One of the first things I learned to do in CSS was how to horizontally and vertically center a fixed width and height element. This could be an image for a splash page (god forbid) or a small centered site that some designers love to do. Originally this was accomplished with absolutely positioning an element 50% from the top and 50% from the left of the viewport. This of course only places the top left corner of the element at the center of the viewport and you then need to drag the element back into a central position with a negative margin equal to half the height and half the width of the element.
Let's take a look at the old way of doing this and note what the problems are.
-
html,body{
-
height:100%;
-
margin:0;
-
padding:0;
-
}
-
body{
-
background:#eae7d7 url(images/vert-centre.jpg) repeat-x center center;
-
text-align:center;
-
min-width:626px;
-
min-height:400px;
-
}
-
#vert-hoz{
-
position:absolute;
-
top:50%;
-
left:50%;
-
margin-top:-198px;/* half elements height*/
-
margin-left:-313px;/* half elements width*/
-
width:624px;
-
height:394px;
-
border:1px solid silver;
-
background:#666;
-
overflow:auto;/* allow content to scroll inside element */
-
text-align:left;
-
}
-
h1 {color:#fff;margin:0;padding:0}
A live version can be found here and the result as shown in the Figure 1 below.
Figure 1

I have added a background image to the body just to make the page look nice so the only part we are really interested in here is the gray centered portion. (As an aside you should note that to get the background image centered in the viewport you need to set html,body to be 100% high.)
As you can see the result is what we wanted and the element is perfectly centered both horizontally and vertically. This is achieved as already mentioned by putting the top left corner of the element at 50% from the top and 50% from the left. Then using a negative top margin and a negative left margin the element is pulled into a central position using half the elements' height and half the elements' width for the appropriate negative margins.
Although at first glance this seems to work well, there are some severe downsides to using this method and they can be seen by closing the browser window both horizontally and vertically. As the window gets smaller than the element's size the element starts sliding out of view at both the top of the window and the left side of the window. The areas that have slid outside the window are now in fact unreachable even by using the scrollbars on the window. This would mean that users with small screen sizes could not access the content at all.
Figure 2 shows what has happened to the one line of text from our example when the window is closed smaller.
Figure 2

The text is half missing at the top and has also disappeared to the left. If we closed the window further the text would disappear completely. In order to try and address these issues a min-height and min-width has been added to the body, but as you can see this has had no effect at all and the element still lies outside the viewport.
Revised Method
In light of these problems another similar version of this centering technique can be used where the element is still placed absolutely from the top but this time the horizontal centering is achieved using auto margins. This also eliminates the element from sliding off the left of the window.
Here is the revised code.
-
html,body{
-
height:100%;
-
margin:0;
-
padding:0;
-
}
-
body{
-
background:#eae7d7 url(images/vert-centre.jpg) repeat-x center center;
-
text-align:center;
-
min-width:626px;
-
min-height:400px;
-
}
-
#vertical{
-
position:absolute;
-
top:50%;
-
margin-top:-198px;/* half main elements height*/
-
left:0;
-
width:100%;
-
}
-
#hoz {
-
width:624px;
-
margin-left:auto;
-
margin-right:auto;
-
height:394px;
-
border:1px solid silver;
-
background:#666;
-
overflow:auto;/* allow content to scroll inside element */
-
text-align:left;
-
}
-
h1 {color:#fff;margin:0;padding:0}
A live version can be found here.
This has the desired effect horizontally but still leaves the top disappearing upwards when the height of the window is made smaller as shown in Figure 3.
Figure 3

The Fix
Now to get over this problem (and to get to the point of this post) I have previously used more complicated methods but there is a simpler, more robust solution involving a float instead of the absolute element.
The first element on the page is a float that is set at 50% of the height of the page. Then we drag the float upward by half the height of the element we want centered.
Here are the changes needed:
-
#vertical{
-
float:left;
-
height:50%;
-
margin-top:-198px;/* half vertical height*/
-
width:100%;
-
}
Here is the link to a live version so you can see for yourself.
Figure 4

The important part is that we use a float of 100% width and then also remember to add clear:both to the following element as some browsers will get confused otherwise. If we did not use "float" then the element would still be centred but it would also disappear through the top of the screen unlike the floated method.
Why This Works
This throws up an interesting behavior concerning floats and it's good to understand what's going on here exactly. Why is it that when we use a static element (or an absolute element as in the first example) that the content disappears through the top of the viewport but doesn't do this with a float?
The nature of floats is that they are removed from the flow (although you can regain control by using "clear" on following elements). The content following a float is displaced to make room for the float (usually by the browser increasing the top margin on the static content to clear the float). If the float were not there at all then the content would occupy its normal position in the page. Therefore when using a negative top margin on a float, the float will travel outside the confines of any containing block because as we stated previously a float is basically removed from the flow. However if we drag the float far enough outside the containing block so that none of it exists inside, then any following content cannot continue to follow the float upwards but resides inside its containing block allowing the float to float way.
This is in fact what happens in our example as the float is dragged upwards away from the body and the following content has to remain inside the containing block formed by the body element. This may be a little hard to understand straight away but can be seen in a simple demo as follows.
-
.float{
-
width:200px;
-
height:100px;
-
background:red;
-
float:left;
-
}
-
.top{
-
background:green;
-
height:300px;
-
width:100%;
-
}
-
.follow-on{
-
clear:both;
-
background:blue;
-
height:100px
-
}
The code above sets a static element at the top of the page followed by a float and then followed by more static content which produces the result seen in figure 5 below and in a live example here.
Figure 5

Nothing special there and all working as expected.
If we next add a 100px negative top margin to the float we get the result as shown in Figure 6.
-
.float{
-
width:200px;
-
height:100px;
-
background:red;
-
float:left;
-
margin-top:-100px
-
}
Figure 6

Still everything as expected but what happens if we increase the negative top margin to 200px?
-
.float{
-
width:200px;
-
height:100px;
-
background:red;
-
float:left;
-
margin-top:-200px
-
}
Figure 7 shows the result once again.
Figure 7

As you can see the float has moved away from the following content but the content that was below the float stays at the top of its own containing block (i.e. beneath the green block). This is exactly what happens when we drag the float outside the viewport in our main example.
However if we were to simply remove the float property from our red div then both the red div and the content below would be dragged up over the green element.
Figure 8

With a static element the flow of the page under the element with the negative margin is changed and all the content is dragged upwards accordingly.
I hope you have enjoyed this little tip (even if you already knew about it) and it shows that there is always something new to learn for all of us. Refer to the original example for the full source code as it is all in the head to be grabbed easily.
If you want to look at some more advanced centering techniques then I have a few other methods documented here. Have Fun!

May 15th, 2008 at 11:06 pm
Nicely explained and illustrated Paul.
May 16th, 2008 at 3:20 am
Thanks John
May 16th, 2008 at 4:45 am
Very nice and thorough!
also add fixed bg positioning to bg body image to prevent vertical scrolling when low browser height.
background:#eae7d7 url(images/vert-centre.jpg) repeat-x center center fixed;
May 16th, 2008 at 6:46 am
Excellent idea and a solution to something that’s kept me stumped for ages. Thank you!
On an unrelated note, you might be interested in the fireshot extension for Firefox (http://screenshot-program.com/fireshot/). It takes snapshots of your browser window (just page content, not the toolbars) and saves them – or if you prefer copies them to the clipboard / opens them in editor of choice etc. Should save you a bit of time mashing the print-screen button!
May 16th, 2008 at 8:32 am
Paul, you really are a mad scientist when it comes to CSS.
May 16th, 2008 at 9:53 am
Thanks for the link Joe – looks useful
May 16th, 2008 at 4:17 pm
[...] Easy Vertical Centering with CSS Related StuffTop reasons your CSS columns are messed up How To: Resizeable Background Image8 fonts you probably don’t use in css, but should47+ Excellent Ajax CSS FormsHow to create a Dock MenuBush CSSLearning CSS For BeginnersFive Free CSS Sliding Door Tab Menus | Blog.SpoonGraphics23 Resources for Clean and Compressed CSSHomer Simpson CSS [...]
May 17th, 2008 at 11:34 am
[...] Easy Vertical Centering with CSS 21 hours agoCSS never ceases to amaze me.A Letter to My Son, on Starting Out In Life | Zen Habits [...]
May 18th, 2008 at 12:01 pm
Interesting!
May 23rd, 2008 at 4:25 am
Thanks for very interesting article. I really enjoyed reading all of your articles. Keep up the good work. See You
May 23rd, 2008 at 2:17 pm
Wow… this is going to help me out so much. I had tried multiple methods and I tried searching, to no avail. I finally came across your post, and I am so glad that i did. Thanks.
May 26th, 2008 at 5:45 am
very nice and clearly explained, thanks a lot.
June 5th, 2008 at 6:32 pm
[...] Easy Vertical Centering with CSS (tags: CSS html tutorial webdev work todo) [...]
June 5th, 2008 at 10:31 pm
[...] Easy Vertical Centering with CSS (tags: computer webdev webdesign design tips) [...]
June 6th, 2008 at 4:33 am
If only this worked for variable height content, not fixed-height blocks.
June 6th, 2008 at 5:10 am
[...] Visit Tutorial [...]
June 6th, 2008 at 8:55 am
Hi Missy,
You’d need a more complicated method such as the following to centre elements of unknown width and height.
http://www.pmob.co.uk/pob/vertical-center1.htm
June 10th, 2008 at 6:36 am
[...] Easy Vertical Centering with CSS (tags: alignment css float centering webdesign vertical horizontal) [...]
June 10th, 2008 at 8:31 am
[...] Easy Vertical Centering with CSS [...]
June 10th, 2008 at 1:30 pm
Nice examples!
June 11th, 2008 at 10:06 am
That’s a good technique, but it’s never-ever gonna validate as Strict due to empty div.
June 13th, 2008 at 7:22 am
LOL this page has multiple H1 tags. Ever heard about semantics??
June 18th, 2008 at 5:02 am
CSS is inferior for vertical alignment. There must something like valign that used for tables.
June 21st, 2008 at 11:47 am
This line:
margin-top:-198px;/* half vertical height*/
Doesn’t this require knowing the elements height. What if that element changed? Would this still work?
July 1st, 2008 at 10:39 am
Thank you so much–you are truly a great benefactor to all designers.
I’ve been hacking around in you excellent code trying to figure out how to float the content not dead V center, but at like 33% from the top which has a definite grace.
The 33% is easy, but getting the top margin to shrink at a ratio is where I’m stuck. Right now the top of my container hits the top of the browser window way before the bottom of the window hits the bottom of the container.
I’m going to keep hacking at it and see if I luck into a solution, but you are the master so I thought I’d throw the problem out there.
Again, thanks so much. You totally rule.
July 4th, 2008 at 9:18 am
I agree with Stephen R.
Show me how this can be resized and I will be impressed.
mc
July 13th, 2008 at 5:01 pm
Woww! Thanks for sharing your information.
July 14th, 2008 at 6:02 am
[...] Vertical Centering with CSS [...]
July 16th, 2008 at 2:58 pm
nice text. thanks
July 17th, 2008 at 10:19 pm
thanks nice information.
August 2nd, 2008 at 4:05 pm
Brilliant!
August 4th, 2008 at 4:39 am
Hi,
In answer to some of the earlier questions (some of which I somehow missed) I have already mentioned that to vertically center elements of unknown dimensions you need a more complicated method as shown in the following demo.
http://www.pmob.co.uk/pob/vertical-center4.htm
August 26th, 2008 at 6:28 am
Hey but what will be happen. when we dont take height of box. how will we can valign the content etc…
October 11th, 2008 at 5:13 am
This technique seems foolproof and You provided great explanation on how it works.
Thank you very much.
October 30th, 2008 at 8:23 am
[...] Easy Vertical Centering with CSS – Excellent tutorial with screenshots on how to perform vertical centering in CSS effectively. [...]
November 5th, 2008 at 10:45 am
I’ve always used the margin tag for horizontal and vertical centering.
Set your width for your #content div tag, which will hold all your content inside it and set the margin as you desire.
ie:
#content {
width:1000px;
margin:0 auto; //horizontal centering
margin:auto 0; //vertical centering
}
hope this helps someone.. saved me a ton of energy
December 4th, 2008 at 10:55 am
@Wholesale:”margin:auto 0; //vertical centering” – Unfortunataly that doesn’t wok and will have no effect on the vertical alignment.
If it did work then there would have been no need for this article
December 4th, 2008 at 10:56 am
Sorry about the spelling in the above post
January 2nd, 2009 at 10:04 am
[...] Easy Vertical Centering with CSS [...]
January 22nd, 2009 at 3:18 pm
* {
padding:0;
margin:0;
}
#centercontaner {
background:#CCCCCC
position:absolute;
text-align:center; /* IE 7 likes this in fact wont work without it*/
width:100%;
background-image:
}
#centercontent{
width:500px;
height:500px;
text-align:center;
background-color: #0000FF;
margin:0 auto;
}
H Center
This will center Horizontally without knowing the width on the object or doing any math. Tested in IE7 and FF, and Safari. Could not test in IE6 I simply don’t have it. So if someone can test would be great. So the question is how to do this vertical.
January 22nd, 2009 at 3:21 pm
Sorry it removed the DIV tags hopfuly this works
div id=”centercontaner”
div id=”centercontent” H Center/div
/div
January 23rd, 2009 at 11:33 am
Hi John,
Thanks for your snippet but I am going to have to correct you on a number of points.:)
First of all you mention that IE7 won’t center without text-align which is nonsense. IE7 will center perfectly well with the margin:auto (combined with a width).
If your IE7 is not centred then you are not using a doctype (or are using a partial or incorrect doctype) and you will have tripped quirks mode in IE which makes it behave more like ie5 and you lose all the benefits of the newer browser.
This will also make IE7 and IE6 use the broken box moodel amongst other unwanted behaviours.
Therefore always use a full valid doctype (with uri).
Secondly there is no need for the absolutely positioned wrapper and it is not needed at all. The text-align:centre is an old hack for ie5.x which doesn’t understand auto margins but incorrectly centres nested block elements (when it shouldn’t).
Thirdly, your routine will not centre widthless elements at all.
Lastly my article shows how to vertically centre so why are you asking that question.
If you want to centre vertically and horizontally elements of unknown height and width then read an old article of mine that shows you how.
http://www.pmob.co.uk/pob/hoz-vert-center.htm
Sorry to take you to task but you so much mis-information in your short post I didn’t want others to be confused by it.:)
February 27th, 2009 at 11:07 pm
it was very helpful
Thanks a lot
April 10th, 2009 at 9:58 pm
It’s encouraging to see all the people who completely missed the point of this. Less real competition for me out there. Thanks Paul. It’s the perfect tool for this particular job. Well worth the meaningless div.
April 12th, 2009 at 5:34 am
Thanks Erik R
May 22nd, 2009 at 7:53 am
Ah, good old tables! It was s-o-o-o-o easy to get a nice easily resizeable page element sitting slap bang in the middle of the page any time you wanted… LOL
Seriously, much as I’m loving CSS (and it’s been a process of learning to love it, that’s for sure) it seems bonkers that we still don’t have an easy way to replicate this supposedly deprecated technological feat. I mean, until CSS3 (and good luck predicting when that will really take hold… HTML5, anyone?) it seems we either have to know the height of an element or make do with something that disappears off the top of the page…
BTW, @Paul OB, thanks for all your generous help. Just thought I should point out that although your other examples work, this one appears stuck to the top of the browser window in IE7…?
http://www.pmob.co.uk/pob/vertical-center4.htm
May 22nd, 2009 at 8:44 am
Hi Chris,
many thanks for pointing out the error in the vertical-center4.htm page. It was just a “haslayout” issue and is working now with the updated fix.
CSS does have the property display:table and is present in IE8 now so these vertical centering issues will be a thing of the past in a couple of years. All other modern browsers have support for display:table anyway so its just IE that was the real problem.
There’s no denting that tables were good for a couple of things such as equal columns and vertical centering but apart from that I never find a design that ever needs a table these days (apart from tablular data of course) and I code hundreds a year for clients.
May 22nd, 2009 at 9:28 am
Hi Paul,
Wow, thanks for the prompt reply!
Yes, I agree, CSS has the :table property but it’s such a shame that it doesn’t do what it says on the tin… Well, maybe it would, but as per usual along comes IE to spoil the party. Without a doubt I spend as long getting sites to work in IE as I do designing them in the first place (if not longer)…
So, just another quick question for you… All these examples focus on centering the page itself. What if you wanted to vertically centre the content of one element, in the manner of an old-style html table tag? Does your solution require any modification for that?
May 22nd, 2009 at 10:30 am
Hi,
The technique is much the same and this is a very very old demo that vertically aligns text content to the middle.
http://www.pmob.co.uk/temp/vertical-align-again.htm
Or an even older demo here:
http://www.pmob.co.uk/temp/vertical-align9.htm
You can also use the inline-block method mentioned in this article.
http://www.search-this.com/2008/08/28/lets-all-get-inline-in-a-block-in-a-block/
Although as you guessed it’s not always straight forward.:)
Hope it’s of some use.
May 24th, 2009 at 4:34 am
Hi Paul,
Much obliged for the reply and links. A few more to add to my collection of Vertical Align CSS bookmarks…
And I’ll know who to call on if I get a tricky CSS projects…
Regards,
Chris G.
July 10th, 2009 at 3:27 am
Thanx,
you are genial
I needet right this one for new site of my rock band, with using Lightwindow script simultaneously. Only this solution is fully function – in another case, after quitting Lightwindow box, the centered content jump up, for unknown reason…
Many thanx once again,
TK
August 24th, 2009 at 3:45 am
Hello Paul. Impressive work but it’s simply to complicated for me. I’ll continue using the valign tag in plain HTML. But do you know if vertical alignment will ever be implemented in CSS? I really don’t understand why the old farts at W3C don’t do something about this. We all want it! So what’s the problem?
August 24th, 2009 at 9:36 am
Hi Jakob,
Thanks for your comments.
There is already an equivalent in css to the deprecated “valign” atttribute (it’s not a tag
) and is simply the “vertical-align” property.
It works in exactly the same way as valign and will vertically align the content in a table-cell (or inline elements in a single line).
There is no need to use the deprecated valign attribute when using tables at all.
Don’tconfuse table behaviour with the behaviour of other block elements as valign does not apply to non-table block elements either so in reality there can be no comparisons.
Yes it would be nice to have an easy vertical align property for block elements which is what I think you are asking. there are explorative specs at the w3c about ways to do this.
http://www.css3.info/advanced-layout-module-gets-a-refresh/
http://www.w3.org/TR/2005/WD-css3-layout-20051215/#vertical
It is possible to vertically align block elements now by setting an element to display:table/cell (which ie8 supports) and then using the vertical align property. (Opera/Firefox and Safari all support this now also).
Re the original article you mention that the solution here is too complicated but the html is actually less code than using a table to do the same thing so I don’t see a problem.:)
October 9th, 2009 at 4:42 am
This is a very nice solution to vertical centering. But… when I add a link to view a site made this way set as blank and IE opens it as a new window and that window is small and the user expands the window it goes all wrong… hoz and ver scroll bar appear and content gets pushed down.
Any ideas how to fix this?
October 9th, 2009 at 9:06 am
Hi Ian,
You’ll have to show me an example so I can see what’s happening. Post a link if you can
You shouldn’t really be opening new resized windows anyway (if that’s what you were doing) as it should be the users choice and not yours.
October 10th, 2009 at 8:15 am
Hi Paul,
I agree you shouldn’t open a new window but many links do.
I used the vert hoz solution “http://www.pmob.co.uk/pob/hoz-vert-center.htm” and that works fine as a pop up.
I trashed the folders from the example but will remake for you to see.
October 10th, 2009 at 8:40 am
Hi Ian,
Yes if you have a link I’ll take a look. I don’t see why it should not work in a small pop up window (but of course IE is always buggy at the best of times).
February 16th, 2010 at 1:17 am
well i like this centering and now i found out why mny ppl said that i have bugs on my web site
i just used old way to do it
Thank you
February 16th, 2010 at 3:23 am
@Sylwester: That would be your code that’s broken and not mine.
Please do no post inane comments without backing them up.
Thank you.
February 16th, 2010 at 3:51 am
@Sylwester: Apologies for the above post I think I misunderstood what you were trying to say
March 13th, 2010 at 11:39 pm
Paul . . . your tutorials are awesome. I however need to vertically center an IMAGE. Right now on the site I just got yesterday Explorer 6 is just crapping on my lovely little vertical alignment CSS (which shows up fine in Firefox what else is new). Just to completely take a dump on my layout scheme, Explorer also ignores the transparency of the gif I want to center — just covering all bases (won’t valign and compromises the background image).
Do you have cross-browser-friendly (non Javascript I beg of you lol) tutorials for images? Thanks Paul. You are ubiquitous!
semicodin
March 15th, 2010 at 8:17 am
Hi Semicodin,
It depends on the context you have and where you want it centred exactly. If it was centred in the browser window like above then you could use the same method as above.
If it’s being centred in another div then it depends on how the page is constructed.
You can centre images vertically like this:
http://www.pmob.co.uk/temp/image-overflow3.htm
http://www.pmob.co.uk/temp/celltest2.htm
http://www.pmob.co.uk/temp/vertical-align11.htm
http://www.pmob.co.uk/temp/vertical-align3.htm
I’d probably need to see your page to see which is best.
March 19th, 2010 at 10:59 am
Thank you very much! You solved my problem very well! So thanks allot!
Greetings from SWE
March 25th, 2010 at 3:02 pm
really appreciate the explanation… using it on a site and it seems to work across the browsers i’ve checked so far (Chrome, Safari, FF, IE8, IE7)… thanks!
May 18th, 2010 at 8:10 am
finally, you saved my life!
I was loking for such a solution for days. the “float-idea” is great!
thank you very very much