Candy, A Journal by a James

On Horizontal CSS Centering using Absolute Positioning or how Relative Positioning can rock your css.

In Joen’s daily work, he needs to centre a div hori­zont­ally. Usually this is easy. It gets a little trick­ier when using abso­lute posi­tioned elements.

[update: read how to do it ver­tic­ally in: ver­tic­ally cent­ring in css (without hacks and multi-line enabled).]

The method I use is to have a wrap­per div with the fol­low­ing css:

.wrapper {
position:relative;
margin:0 auto;
text-align:left;

width:whatever;
}

For good meas­ure, you’ll need to apply the IE fix:
body { text-align:center; }
And yes indeed, the “text-align:left” of the wrap­per makes sure the text aligns to the left again.

Now you’re free to abso­lutely pos­i­tion the con­tent using the wrap­per as ref­er­ence point. This is due to the fact that an ele­ment with position:relative applied to it forces every ele­ment inside it (the so called child ele­ment) to use the par­ent as ref­er­ence, not the view­port (the part of the browser in which a web page is dis­played). You could say it resets the ref­er­ence point of it’s chil­dren elements.

This means you can still use abso­lute pos­i­tion­ing while cent­ring the whole page, like so:

.content {
position: absolute;
left: whatever;
top: whatever;

width: whatever;
}

In this spe­cific case, he needed a div to be placed over some Flash con­tent. Good news: It works like a charm for pos­i­tion­ing some­thing over Flash!

So there you have it, cross browser cent­ring of abso­lute & rel­at­ive posi­tioned divs work­ing in mod­ern browsers such as Mozilla Firefox, Opera & Safari as well as the ye olde Internet Explorer. Hope this lil’ art­icle has been use­ful to you.

84 Responses to “On Horizontal CSS Centering using Absolute Positioning or how Relative Positioning can rock your css.”

  1. Sandra says:

    If there were no prob­lems, design­ing and devel­op­ing web­sites would be easy… but not as fun & interesting! :)

    I did get the 100% height to work. I needed 100% height so that the back­ground image con­tin­ued to the bot­tom of the page. It’s work­ing, but there is a gap at the end of the page and you scroll to see noth­ing but the body’s back­ground col­our. I’m going to com­pare the gap’s size to the pad­ding and mar­gin meas­ure­ments and see if that’s got any­thing to do with it.

    I’ll sumarise the code and post it if you’d like.

    BTW: I had a dif­fer­ent z-index prob­lem. The logo in the top left corner has a trans­par­ent lower corner and that was cov­er­ing the top of the con­tent sec­tion, block­ing the use of links and also high­light­ing. That’s all fixed now! :)

  2. Sandra says:

    Hi again,

    I fixed the gap, that was simple. The 100% height works in IE but not FF… which prob­ably means that it doesn’t really work… I think. IE takes you to mean 100% of the page length (no mat­ter how long it is), but FF thinks 100% of the win­dow height.

    Back to square one… again.

  3. Dana says:

    Brilliant! Thanks very much for blog­ging this, saved me lots of tinker­ing as well.

  4. Gary says:

    Thanks for this trick. It addresses exactly the prob­lem I am hav­ing with cre­at­ing fly­out menus on a centered page design. It works like a charm in IE but I can­not get it to work in Firefox. I haven’t seen any reports of the same prob­lem in the pre­vi­ous responses… so what am I miss­ing? Any suggestions?

  5. annoyed says:

    why is fixed pos­i­tion­ing meant to be so good when you can­not write a para­graph of text and float and image around it. Think about it. It means its so stu­pid! Unless there is a way?

  6. annoyed says:

    oh hang on you can by using class names. HO HO HO, whoops

  7. Well there you go, ‘annoyed’!

    Dana: Glad it was of use to you.

    Gary: You prob­ably missed giv­ing your con­tainer (the thing you’re cent­ring) a width; that’s the most com­mon mis­hap anyway ;)

  8. Gary says:

    Thanks for the response James. I do have the width defined both as part of the css rule and in the html table tag (the table being the con­tainer). I have been exper­i­ment­ing with the place­ment of the con­tent div either dir­ectly in the table an in td’s (with the wrap­per class applied) but the same res­ult in fire­fox. It all works great in IE, though. :( Here is the rel­ev­ant css I am using. Any other thoughts?

    .wrap­per {
    pos­i­tion: rel­at­ive;
    mar­gin: 0 auto;
    text-align: left;
    width: 800px;
    }

    .wil­cMenu {
    pos­i­tion: abso­lute;
    top: 25px;
    left: 29px;
    background-color:#663333;
    width: 100px;
    height: 20px;
    z-index: 10;
    color: #ffffff;
    }

  9. CitizenZed says:

    Ha Ha.… Spare the wrap­per, spoil the child!

    Thank you.… god!? Now I need to cipher what the “IE fix” is all about. But any­way, you rule ;p

  10. Thank you Zed, glad to know I could help you out :)

  11. helena says:

    heeey!
    thanks alot!
    works perfect!

  12. Helena: Great!

    Gary: Have you given your flash (assum­ing it flies out over that) a lower z-index? And could you link to an example?

  13. Dzub says:

    This is a great solu­tion, thanks for shar­ing!
    While imple­ment­ing this CSS I was try­ing to place a DIV under the wrap­per and found it very hard to do. The only solu­tion I came up with was to cre­ate another DIV position:absolute; and give it top:125%; (or a value greater than 100%). The prob­lem I encounter is that dif­fer­ent browsers inter­pret the top per­cent­age value dif­fer­ently and I can not get con­sist­ent pos­i­tion­ing across dif­fer­ent browsers on win/mac machines. Is there a solu­tion for this?

  14. Stfn says:

    Does any­one have the same prob­lem as I with this in FireFox (v2.0.0.4)? It works fine if the width of the browser is a bit big­ger than the wrap­per, but if not it’s like the wrap­per has a mar­gin and gets “stuck” when you min­im­ize the browser too much.

    This page has that same error from my com­puter anyway.

  15. Stfn says:

    Btw; the scroll is left out­side the min­im­ized area, and that is a big prob­lem I think…

  16. sain says:

    I want to cen­ter the container(wrapper) div while its height should be 100% and should cover the screen area ver­tic­ally… i have done some­thing like this..
    con­tainer {
    background-color: #78C1FE;
    height: 100%;
    pos­i­tion: abso­lute;
    width: 774px;
    text-align:left;
    }

    #header {
    background-color: #0099FF;
    height: 150px;
    width: 774px;
    }

    #logo {
    float: left;
    height: 150px;
    text-align: left;
    width: 50%;
    }

    #log­oright {
    float: right;
    height: 150px;
    pos­i­tion: fixed;
    text-align: left;
    width: 50%;
    }

    #con­tent {
    background-color: #78C1FE;
    height: 100%;
    width: 774px;
    }

    #footer {
    background-color: #FF9900;
    height: 80px;
    width: 774px;
    }

    body {
    margin-left: 0px;
    margin-top: 0px;
    text-align:center;
    }

    but the thing is it does not work… i also want the footer div to stay at the bot­tom of the page (please refer the prop­er­ties of footer div in the css) while the con­tent are should cover the rest of the space (so i have set its height to 100%) while it should leave 150px height to header… it works but scroll bar comes up which i don’t want.

    please help

  17. Sain, I think the solu­tion you want is more than adequately explained over at 456 Berea Street: CSS Frames v2 Full Height by the most esteemed Roger Johansson.

  18. Stfn: To com­bat that you make sure that the wrap­per includes a mar­gin. (Unlike this site at present, yes.)

  19. Zack says:

    Can any­one tell me how to get an image to be cen­ter and abso­lute at the bot­tom of the window? :)

    I’m hav­ing a tough time get­ting it, I’m pretty new at CSS :(

    When I pos­i­tion: abso­lute;
    and bot­tom: 10px;

    it will do it and hang out there at the bot­tom per­fectly, but I can’t get it centered :(

    any help would be great!

  20. Zach: put a “position:relative;” on its con­tain­ing ele­ment (which could be the body ele­ment or some div which holds the image).

    Then add “mar­gin: 0 auto;” on the ele­ment you’re try­ing to get in the centre at the bottom.

    That should do the trick!

  21. Shaun Parker says:

    Okay, I have been look­ing all over the inter­net and still have yet to find an answer to my ques­tion. I am look­ing to cen­ter a div, this post does show how to do it, the prob­lem is that I also want the page wrapper/container to have a height of 100% even when the con­tent doesn’t fill the screen. I can do this by using the pos­i­tion: abso­lute so the height: 100% has some­thing to scale to, but when I use an abso­lute pos­i­tion­ing I can no longer use the mar­gin: 0 auto.

    So, may ques­tion for the masses is this: How do you cen­ter a div ele­ment and make it’s height truly 100%? I could do this with javas­cript, but I’m look­ing for a 100% CSS solution.

    If you can answer this, I love you…

    Thanks in advance :),
    Shaun

    PS — I don’t want to use the neg­at­ive mar­gin trick.

  22. Jordefamn says:

    This solu­tion helped really helped me!
    I’d tried rel­at­ive pos­i­tion­ing, neg­at­ive mar­gins…
    This one really did the trick, and I’ve been look­ing for this kind of solu­tion for some time.
    Thank you kindly!

  23. Gary Badger says:

    Your solu­tion appeared too simple to fix [what seemed to be] a com­plex prob­lem. Boy, was I wrong! All of my prob­lems have been solved with just 3 new lines of CSS. Wish I’d found you hours ago!

    Thank you very much James, you are a lifesaver.

    Cheers,
    Gary

  24. Shaun: A con­tainer within a con­tainer *should* do the trick.

    Jordefamn & Gary: You’re both very welcome!

  25. Thanks alot! I was mess­ing around with this for two days now.

    Jens

  26. Diezko says:

    works gooood !!!! XD Thanks!

  27. Gary says:

    Thank you thank you thank you thank you.
    That’s been bug­ging me for hours now…

  28. Lawrence says:

    arg.. I need to cen­ter a back­ground that is ran­domly chosen with a javas­cript script… except I want it to cen­ter hori­zont­ally so if they change the width, it will keep the image centered, but i DON’T want it to stay centered ver­tic­ally… and if it does, I can’t think of how to keep my other divs at the cor­rect heights since they are smal­ler and they don’t change equally :S kinda sucky cuz it seems that if I use background-position cen­ter then it goes crazy in moz­illa and gets stuck at the top because moz­illa requires fixed attach­ment… but that makes the damn ver­tical scroll! HALP MEH! :(

  29. Calm down.

    Don’t you just want “background:#fff url(wha.jpg) top cen­ter no-repeat;” ?

  30. DB-Elements says:

    Awesome post! I have read else­where that abso­lute pos­i­tion­ing is not good for browsers that can adjust text size, as it will cause the text within the abso­lute divs to expand past it’s bound­ar­ies. Although I haven’t exper­i­enced this, has any­one else?

    I’m look­ing for an altern­at­ive to using mul­tiple floats, mar­gins, and bor­ders, as a way to avoid imple­ment­ing sev­eral IE6 hacks. Opinions on Absolute Positioning lay­outs vs Float lay­outs would be greatly appre­ci­ated. Thanks again for the post.

    • [..] abso­lute pos­i­tion­ing is not good for browsers that can adjust text size [..]

      Happily, that’s just not true. What I think people were get­ting at (or con­fus­ing with) is the case where someone sets a height & width in px, and then finds that text grows bey­ond that. Simply not set­ting the height solves that, and the prob­lem (and solu­tion) isn’t inher­itly tied to abso­lute pos­i­tion­ing anyway.

      [..] avoid imple­ment­ing sev­eral IE6 hacks [..]

      You should really avoid IE hacks com­pletely, and use Conditional Comments (Simon Clayson’s art­icle on tar­get­ing (dif­fer­ent) IE (ver­sions) is the best). This allows you to feed IE6/7/8 dif­fer­ent mar­gins & pad­ding, without muck­ing up the rest of your code.

      But to answer the under­ly­ing ques­tion of not need­ing to resort to dif­fer­ent CSS for IE: The best way, still, is to avoid any margin-collapse situ­ations, use either mar­gin or pad­ding on any one ele­ment. This does lead to more wrapper-divs, so it is controversial.

      Another way is to simply reset the box model (so it matches IE 5s), but that has some prob­lems too, even if con­cep­tu­ally it is superior.

  31. Reaperofdb says:

    I am using the text-align:center; wrap­per method with abso­lute pos­i­tion­ing in the con­tent block of text but my page con­tin­ues to hug the right side of the window.

    Either I take out the abso­lute value part and the cen­ter­ing works, or I leave in both and get only top pos­i­tion­ing (top:0px) and the con­tent hug­ging the right…

    .wrap­per {
    text-align:center;
    }
    .content {

    position:absolute;
    top:0px;
    width:75%;
    height:500;
    background-color: #326512;
    text-align:left;
    padding:5px;

    }

    This is the code I’m using, and the browser for test­ing I’m using is Internet Explorer 7

    • You need to change “position:absolute;” a “position:relative;” for your .con­tent, how­ever, it’s advis­able to change .wrap­per to body and .con­tent to .wrap­per, as that’s essen­tially what you’re doing.

Care to Comment?