May 15th, 2008 - by Paul OB

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.

[CSS]
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}
[/CSS]

[HTML]

Content goes here

[/HTML]

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.
[CSS]
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}

[/css]

[HTML]

Content goes here

[/HTML]

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:

[CSS]
#vertical{
float:left;
height:50%;
margin-top:-198px;/* half vertical height*/
width:100%;
}
[/CSS]

[HTML]

Content goes here

[/HTML]

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.

  1. .float{
  2.     width:200px;
  3.     height:100px;
  4.     background:red;
  5.     float:left;
  6. }
  7. .top{
  8.     background:green;
  9.     height:300px;
  10.     width:100%;
  11. }
  12. .follow-on{
  13.     clear:both;
  14.     background:blue;
  15.     height:100px
  16. }
  1. <div class="top">Top</div>
  2. <div class="float">Float</div>
  3. <div class="follow-on">Following content</div>

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.

  1. .float{
  2.     width:200px;
  3.     height:100px;
  4.     background:red;
  5.     float:left;
  6.     margin-top:-100px
  7. }

Figure 6

Still everything as expected but what happens if we increase the negative top margin to 200px?

  1. .float{
  2.     width:200px;
  3.     height:100px;
  4.     background:red;
  5.     float:left;
  6.     margin-top:-200px
  7. }

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!

73 Responses to “Easy Vertical Centering with CSS”

1 John

Nicely explained and illustrated Paul. :)

2 Paul OB

Thanks John :)

3  

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;

4 Joe Banner

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!

5 Golgotha

Paul, you really are a mad scientist when it comes to CSS.

6 Paul OB

Thanks for the link Joe – looks useful :)

[…] 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 […]

8 links for 2008-05-17 | iKeif

[…] 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 […]

9 Chaim

Interesting!

10 Najlepsze Ogłoszenia

Thanks for very interesting article. I really enjoyed reading all of your articles. Keep up the good work. See You

11 Wii Fit Accessories

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.

12 świr

very nice and clearly explained, thanks a lot.

13 links for 2008-06-06 at found_drama

[…] Easy Vertical Centering with CSS (tags: CSS html tutorial webdev work todo) […]

14 links for 2008-06-06 « Donghai Ma

[…] Easy Vertical Centering with CSS (tags: computer webdev webdesign design tips) […]

15 Missy

If only this worked for variable height content, not fixed-height blocks.

[…] Visit Tutorial […]

17 Paul OB

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

18 Liens du jour - Barbablog

[…] Easy Vertical Centering with CSS (tags: alignment css float centering webdesign vertical horizontal) […]

[…] Easy Vertical Centering with CSS […]

20 Oliver Kiss

Nice examples!

21 Mariusz

That’s a good technique, but it’s never-ever gonna validate as Strict due to empty div.

22 Jacco

LOL this page has multiple H1 tags. Ever heard about semantics??

23 Oguzhan

CSS is inferior for vertical alignment. There must something like valign that used for tables.

24 Stephen R

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?

25 Dot Mike

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.

26 Michael

I agree with Stephen R.

Show me how this can be resized and I will be impressed.

mc

27 Egypt Web Design

Woww! Thanks for sharing your information.

[…] Vertical Centering with CSS […]

29 cssmake

nice text. thanks

30 Egypt Web Designe

thanks nice information.

31 menerronse

Brilliant!

32 Paul OB

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

33 vijay

Hey but what will be happen. when we dont take height of box. how will we can valign the content etc…

34 Kamil Szot

This technique seems foolproof and You provided great explanation on how it works.

Thank you very much.

35 The Geek Stuff » Around The Geek World - Oct 2008

[…] Easy Vertical Centering with CSS – Excellent tutorial with screenshots on how to perform vertical centering in CSS effectively. […]

36 Wholesale

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

37 Paul OB

@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 :)

38 Paul OB

Sorry about the spelling in the above post :)

[…] Easy Vertical Centering with CSS […]

40 John

* {
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.

41 John

Sorry it removed the DIV tags hopfuly this works

div id=”centercontaner”
div id=”centercontent” H Center/div
/div

42 Paul OB

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.:)

43 Wizola Search

it was very helpful
Thanks a lot

44 Erik R

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.

45 Paul OB

Thanks Erik R :)

46 Chris Greenhough

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

47 Paul OB

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. :)

48 Chris Greenhough

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?

49 Paul OB

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.

50 Chris Greenhough

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.

51 Tom Key

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

52 Jakob G

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?

53 Paul OB

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.:)

54 Ian

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?

55 Paul OB

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.

56 Ian

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.

57 Paul OB

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).

58 Sylwester w Górach

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 :P

Thank you

59 Paul OB

@Sylwester: That would be your code that’s broken and not mine.

Please do no post inane comments without backing them up.

Thank you.

60 Paul OB

@Sylwester: Apologies for the above post I think I misunderstood what you were trying to say :)

61 semicodin

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

62 Paul OB

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.

63 Juju

Thank you very much! You solved my problem very well! So thanks allot!

Greetings from SWE

64 biscuit

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!

65 maosmurf

finally, you saved my life!
I was loking for such a solution for days. the “float-idea” is great!

thank you very very much ;)

66 MikeF

Wow, so much simpler and more effective than the other methods I have found. Not something that I even thought about until I needed it. Great to find such a brilliant explanation. Thanks so much

67 Kenny Fix

Rare that i bother to leave any comment… i usually grab what i need and run, but this explanation is spot on… big thanks to the nice man with the #vertical plan!

68 Paul OB

Thanks Kenny :)

69 Jeremy

Well, it’s been a year since the last comment, but I’ll take a shot. This works great, of course, but I’m desperately trying to float a logo OUTSIDE the centered container that will lock to the top left of the container and disappear offscreen before the content when the window is compressed.

I’ve achieved this using a different centering CSS method, but I much prefer this one if I can get the same result.

70 Paul OB

Hi Jeremy,

You should be able to do that quite easily.

Just drag our element upwards from inside the container.
.logo {
width:200px;
height:100px;
background:red;
margin:-110px 0 0;
float:left;
}

You will have to remove the overflow from #hoz or it won’t show. If you need to have scrollable content in the middle then you will need to nest an inner div and apply the overflow to that instead leaving the logo outside of that div.

71 Jeremy

Thanks so much. I had tried that and everything else I could think of, but it was the #hoz overflow that I was missing.

72 hestroy

Great work, man. Thanx!

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading