Return to Candy by James homepage

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.

Have a look at more Code or CSS or Web or Worthy

86 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. 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;
    }

  22. sercy D says:

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

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

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

  25. Nick Herren says:

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

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

  27. Mark Brown says:

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

  28. milo says:

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

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

    Milo: Hope you man­age it!

  30. Dan K. says:

    Worked for me! Thanks!

  31. 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!

  32. Fred S says:

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

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

  34. 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/

  35. 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…

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

  37. 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!

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

  39. Cy says:

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

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

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

  42. Cy says:

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

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

  44. 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?

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

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

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

  48. 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?

  49. 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!

Possibly related content

  1. Vertically centring in css (without hacks and multi-line enabled)
  2. Elastic, Liquid, Pixel: Explained.
  3. CSS3 @font-face browser support table
  4. Bye bye liquid layouts!
  5. Full page zoom (update)