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. stroke says:

    short, simple, effect­ive. i want more. :)

  2. AkaXakA says:

    We aim to please sir…any suggestions?

  3. BlueIce says:

    I had to spe­cify the width of the wrap­per for it to work in IE6
    Appart from that… THANKS A LOT… it’s the only solu­tion I’ve found which works in both IE and Firefox… and it doesn’t involve any scripting !

  4. Eddie says:

    Worked won­der­fully. Thanks for shar­ing this awe­some solution. :)

  5. AkaXakA says:

    Good to hear guys! But remem­ber — this is exactly what css was cre­ated (in part) to do.

  6. trevdak says:

    I was look­ing for an answer to my CSS woes, your page provided it.

    Thanks a bunch.

  7. yves says:

    This sounds like what I am look­ing for. I am almost done a site and was just asked to include a logo in the bot­tom right corner of each page — I would have to redesign each page if I have to use tables.

    So if I under­stand cor­rectly, the wrap­per can be applied to my main container(a table) and then the pos­i­tion­ing of my DIV(containing my image) will be posi­tioned in ref­er­ence to my main container(to which the wrap­per has been applied)?

  8. Ah, the bottom-right! There’s a lot of CSS issues there in browsers.

    Don’t know if it mat­ters in tables that the [table] wouldn’t be the dir­ect par­ent of the [div] you’re try­ing to position…depending on the design, maybe insert­ing the div under­neath the table, clear­ing both the table and the div and then using a neg­at­ive mar­gin to bring it up (if needed) would be better.

  9. Joen says:

    Hey James,

    I’d just like to point out that I used this solu­tion for a pro­ject at work, and it worked WONDERFULLY. It was easy, quick, and sur­pris­ingly com­pat­ible. Once I man­aged to wrap my mind around your solu­tion, it was sur­pris­ingly simple. Suddenly “pos­i­tion: rel­at­ive” makes sense to me (and I’ll be using it for every #con­tainer I cre­ate from now on).

    So thanks, you’ve saved my butt today.

  10. Brian says:

    What about when u want to have a footer appear below these “pos­i­tion: abso­lute” columns?

    Doing a “clear:both” doesn’t work.

  11. Charles says:

    first off, thank you so much, this is a beau­ti­ful fix to a con­stant prob­lem for me.

    secondly though, it throws things com­pletely out of whack in safari, and I can’t think for the life of me how to fix it.

    any help would be greatly appre­ci­ated, thanks,

  12. What hap­pens in Safari then?

  13. AyaConcepts says:

    I’m hav­ing trouble with both rel­at­ive and margin:0 auto; to work together to cen­ter the page. I’ve always seen that margin:auto and rel­at­ive pos­i­tion­ing were incompatible.

    Right now I’m using the abso­lute pos­i­tion at 50% then a neg­at­ive mar­gin of half my width, but of course I ran into the prob­lem of when the win­dow is scaled down or when run­ning at 800×600 res­ol­u­tion, I can­not scroll to the top and left due to the neg­at­ive mar­gin. any help is wel­come, the work site I’m work­ing on to fix the prob­lem is http://www.ayaconcepts.com/brmt2/

  14. AyaConcepts says:

    never mind, rookie mis­take =p. didn’t set my .wrap­per width and height.

    thanks a lot!!!

    now…about ver­tical cen­ter­ing =D… haha

    the jour­ney never ends!

  15. Well glad I could help!

  16. Michael Johnston says:

    Here are some “struts & springs” examples that may help people with ver­tical cen­ter­ing, fixed size gut­ters, etc.

    .con­tainer {
    pos­i­tion: rel­at­ive;
    mar­gin: 20px auto;
    back­ground: #ff9999;
    bor­der: 4px solid green;
    height: 30%;
    }
    #left­stuff {
    pos­i­tion: abso­lute;
    left: 10px;
    top: 20px;
    height: 50px;
    back­ground: #999999;
    bor­der: 1px solid black;
    }

    #middlepin {
    pos­i­tion: abso­lute;
    left:0%;
    right: 50%;
    }

    #mid­dlestuff {
    pos­i­tion: abso­lute;
    left: 80px;
    right: 5px;
    top: 25px;
    back­ground: #999999;
    bor­der: 1px solid black;
    }
    #right­stuff {
    pos­i­tion: abso­lute;
    left: 50%;
    right: 10px;
    bot­tom: 0px;
    top: 0%;
    back­ground: #999999;
    bor­der: 1px solid black;
    }

    #center­pin {
    pos­i­tion: abso­lute;
    top: 0px;
    bottom:50%;
    bor­der: 2px solid red;
    }
    #middlestuff2 {
    pos­i­tion: abso­lute;
    bot­tom: –25px;
    height: 50px;
    back­ground: #999999;
    bor­der: 1px solid black;
    }

    blah
    blah
    blah

    left blah, blah
    middle blah, blah
    right blah, blah

    blah
    blah

    middle blah, blah

  17. Michael Johnston says:

    ok, well so much for that. Let’s try pre:

    .con­tainer {
    pos­i­tion: rel­at­ive;
    mar­gin: 20px auto;
    back­ground: #ff9999;
    bor­der: 4px solid green;
    height: 30%;
    }
    #left­stuff {
    pos­i­tion: abso­lute;
    left: 10px;
    top: 20px;
    height: 50px;
    back­ground: #999999;
    bor­der: 1px solid black;
    }

    #middlepin {
    pos­i­tion: abso­lute;
    left:0%;
    right: 50%;
    }

    #mid­dlestuff {
    pos­i­tion: abso­lute;
    left: 80px;
    right: 5px;
    top: 25px;
    back­ground: #999999;
    bor­der: 1px solid black;
    }
    #right­stuff {
    pos­i­tion: abso­lute;
    left: 50%;
    right: 10px;
    bot­tom: 0px;
    top: 0%;
    back­ground: #999999;
    bor­der: 1px solid black;
    }

    #center­pin {
    pos­i­tion: abso­lute;
    top: 0px;
    bottom:50%;
    bor­der: 2px solid red;
    }
    #middlestuff2 {
    pos­i­tion: abso­lute;
    bot­tom: –25px;
    height: 50px;
    back­ground: #999999;
    bor­der: 1px solid black;
    }

    blah
    blah
    blah

    left blah, blah
    middle blah, blah
    right blah, blah

    blah
    blah

    middle blah, blah

  18. Michael Johnston says:

    ok, never mind

  19. Steven says:

    Exactly what I was look­ing for! Very clever and it works per­fectly. Combining this with appro­pri­ate use of em val­ues, I was able to make my entire page scal­able for vis­it­ors that are visu­ally impaired. The only thing that was remain­ing was a text over­lay I had over an image…and thanks to your clever work, it turned out per­fect! Thanks!

  20. Marko says:

    This is great stuff. Thanks a lot.

  21. Glad to hear it!

  22. Ben Hunt says:

    I’ve just worked through a prob­lem with this approach, which led me to go back to the old way (see below)…

    The prob­lem is that, when all the page con­tent is con­tained within the “wrap­per” div, and that div is absolute-positioned, the browser doesn’t know where then end of the body is.

    I wanted a bottom-aligned image on the body, but couldn’t come up with a way of for­cing Firefox to treat the end of the doc­u­ment as the end of the body! (I got it to work in Internet Exploder though!!)

    Only a prob­lem if you want a bottom-aligned image, it seems..

    So, I’ve resor­ted to this:

    body{
    background:#f9f9f9;
    background-image:url(images/bg_body.gif);
    background-position:bottom left;
    background-repeat:repeat-x;
    text-align:center;
    }
    #wrap­per {
    width:772px;
    margin:0 auto;
    text-align:left;
    }

  23. sercy D says:

    Does the wrap­per go on the .css file or in the css area of the page

  24. With CSS that doesn’t mat­ter. You can put it any­where you like!

  25. Nick Herren says:

    This solu­tion sounds like it should work great and I can see that oth­ers have used it suc­cess­fully. I have copied the code exactly as you wrote it and it simply will not work. I know I may simply be over­look­ing the obvi­ous. I have tried adjust­ing the width from auto to 100% and also chan­ging my DIVs from ID to Class since that is how you wrote it. None of this seems to work. I was won­der­ing if per­haps the type of rollover I am using (shift­ing a mul­ti­part image) may be the prob­lem. I really am at a loss but I would like to use your solu­tion and am try­ing to solve this prob­lem before I add any php or code to the page. Any help is appre­ci­ated. http://www.humdilly.com/humdilly/events/cats.php

  26. Nick Herren says:

    I for­got to men­tion I am using Mozilla and have tried it in IE6 as well with no luck.

  27. Nick Herren says:

    Forgive my series of responses here but I did man­age to get it to work (not per­fectly tho) when I put in a width pixel range between 400 and 800. It did not work when I tried 1200px tho. Very strange.

  28. Mark Brown says:

    Excellent. Why ever did they remove the float option in CSS :(

  29. milo says:

    Interesting, will try it on my site, if it works, i’ll give a reply.

  30. Mark: Remove what float option? Of course Floating still works in CSS!

    Milo: Hope you man­age it!

  31. Dan K. says:

    Worked for me! Thanks!

  32. rubhadubh says:

    Just exactly what I needed to know — saved me hours of tinker­ing. I sus­pect that I’ll be using this solu­tion a lot — thanks!

  33. Fred S says:

    How did you make the div go OVER the flash again? Flash wants to stay on top for me.

  34. By adding “z-index:5;” to your rules for #con­tent. (In this example)

  35. Cy says:

    This is a won­der­ful solu­tion. I just have a couple of caveats:

    1. I need this to work con­sist­ently in FireFox, IE 6+, and Safari with a Flash element…

    2. The Flash fix is great (using the z-index), but I’m try­ing to pos­i­tion a DHTML gen­er­ated fly­out menu over the Flash with this method. The pos­i­tion­ing is fine, but the menu fly­outs (sub’s) are a bit wonky. Your solu­tion works beau­ti­fully in FireFox, haven’t been able to test it in IE yet, but in Safari the menu fly­outs “vibrate” when cross­ing over the Flash. Is there any­way to fix this? I can’t ignore the Safari people…they com­prise appx 15% of the vis­it­ors to my site…

    FYI…the DHTML menu I’m con­sid­er­ing using is from TwinHelix: http://www.twinhelix.com/dhtml/fsmenu/

  36. Cy says:

    Just an update to my last message…with this pos­i­tion­ing method the DHTML menu over Flash works beau­ti­fully in IE & FireFox on a PC. But, still need to solve the Safari issues for a Mac…

  37. Cy: You should be able to get them work­ing by adding z-index:5; (the num­ber refer­ing to a layer higher than the Flash con­tent) to your sub­menu css:
    ul.menu li ul {z-index:5;}
    You might also need to add position:relative; or position:absolute; to them too, as they might not have it already.

    Good luck!

    Edit: Just saw your second mes­sage. In case you haven’t done what I’ve described above, try that. Otherwise I’ll send some guys round (now that sounds wrong) who know the trap­pings of Safari.

  38. Cy says:

    Thanks for the response…I already have the z-index for the DHTML menu and its sub’s set to a value below the Flash. (The z for the menus is “5” and the Flash is at “100”.) Again…works well in everything but Safari on a Mac.

    If you are on a Mac and have Safari…look at the Adobe web­site (www.adobe.com). They are try­ing to do the same thing (run a menu over the Flash). Works well in everything but Safari…

    Ideas? :) Thanks!

  39. Eh? Try giv­ing the menus a value above Flash. (Since you want the submenu’s over the Flash, right?)

  40. Cy says:

    Tried that already…the menu opens behind the Flash…which I don’t want it to do… Ideas?!? :)

  41. Cy says:

    Sorry! Totally mispoke earlier… the z-index for the Flash is at “5” and the menus and their subs at “100”, so that the menus are on top of the Flash.

  42. You have put “[param name=“wmode” value=“transparent”] ” in your html for the flash object, right? (or opaque instead of transparent)

  43. Cy says:

    Yes, I have it set to ‘trans­par­ent’. For kicks, I also tried ‘opaque’ and it made no difference…

  44. Your best bet is a bit of JavaScript. Veerle’s got an art­icle on it: Experimenting with Flash Content and z-index

  45. Sandra says:

    Hi! :)
    Thanks for the inform­a­tion, very help­ful! :)
    now… just got to fix the other IE prob­lems that I am hav­ing… hope it’s just the z-index around the wrong way…

    Is it easier/better to cre­ate a page for IE or fix it for IE last?

  46. It’s far easier (even­tu­ally) to fix for IE last. Any other way and all the code gets mucky. ;)

    Also, just to be clear, a higher z-index means it’ll go *above* some­thing with a lower z-index.

  47. Sandra says:

    Hi James,

    Thanks for the inform­a­tion. The prob­lem was the divs had to be 100% height (and a couple of other little things) to look cor­rect — I just assumed that it was the z-index as it looked like another div was cov­er­ing it up.

    Now I’ve got to look into hav­ing a seper­ate style sheet for print­ing the page, which sounds like fun! :)

    Must cre­ate for IE last… Else code gets mucky… Must learn from this mis­take… MUST REMEMBER!!!! :)

  48. Penny Aguilera says:

    Ran accross your cen­ter­ing DIV info today. Been look­ing FOREVER for a way to keep centered con­tent from “exit­ing left” when the browser win­dow was less wide then the content…

    Your way is THE BEST!
    Thanks.

  49. Anton says:

    This is very help­ful but at the same time as cen­ter­ing this DIV i need to also make it 100% height. So the rel­at­ive wrap­per kills my idea in this case.
    Similar to what Sandra is try­ing to do i think!
    Any thoughts?

  50. Yes, sadly “position:relative;” does kill that. The only way to get (min­imum) 100% prop­erly is with a table, or with a div that acts like one. Which is easy enough, as you can just slap a “display:table” onto it — but. Of course, there is a but, as IE6+7 (and before) don’t sup­port it.

    The other way is to give the #con­tent a “position:fixed” & “height:100%”, and to have the other con­tent scroll under it. Depending on your design this may look really cool or really awful.

    This is, how­ever, the old­est prob­lem of CSS, so you might bet­ter helped by look­ing up a ready-made CSS page with 100% height, and apply­ing what you’ve learnt here to that.

    Good luck Anton & Sandra!

Care to Comment?