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 horizontally. Usually this is easy. It gets a little trickier when using absolute positioned elements.
[update: read how to do it vertically in: vertically centring in css (without hacks and multi-line enabled).]
The method I use is to have a wrapper div with the following css:
.wrapper {
position:relative;
margin:0 auto;
text-align:left;
width:whatever;
}
For good measure, you’ll need to apply the IE fix:
body { text-align:center; }
And yes indeed, the “text-align:left” of the wrapper makes sure the text aligns to the left again.
Now you’re free to absolutely position the content using the wrapper as reference point. This is due to the fact that an element with position:relative applied to it forces every element inside it (the so called child element) to use the parent as reference, not the viewport (the part of the browser in which a web page is displayed). You could say it resets the reference point of it’s children elements.
This means you can still use absolute positioning while centring the whole page, like so:
.content {
position: absolute;
left: whatever;
top: whatever;
width: whatever;
}
In this specific case, he needed a div to be placed over some Flash content. Good news: It works like a charm for positioning something over Flash!
So there you have it, cross browser centring of absolute & relative positioned divs working in modern browsers such as Mozilla Firefox, Opera & Safari as well as the ye olde Internet Explorer. Hope this lil’ article has been useful to you.

short, simple, effective. i want more. :)
We aim to please sir…any suggestions?
I had to specify the width of the wrapper for it to work in IE6
Appart from that… THANKS A LOT… it’s the only solution I’ve found which works in both IE and Firefox… and it doesn’t involve any scripting !
Worked wonderfully. Thanks for sharing this awesome solution. :)
Good to hear guys! But remember — this is exactly what css was created (in part) to do.
I was looking for an answer to my CSS woes, your page provided it.
Thanks a bunch.
This sounds like what I am looking for. I am almost done a site and was just asked to include a logo in the bottom right corner of each page — I would have to redesign each page if I have to use tables.
So if I understand correctly, the wrapper can be applied to my main container(a table) and then the positioning of my DIV(containing my image) will be positioned in reference to my main container(to which the wrapper has been applied)?
Ah, the bottom-right! There’s a lot of CSS issues there in browsers.
Don’t know if it matters in tables that the [table] wouldn’t be the direct parent of the [div] you’re trying to position…depending on the design, maybe inserting the div underneath the table, clearing both the table and the div and then using a negative margin to bring it up (if needed) would be better.
Hey James,
I’d just like to point out that I used this solution for a project at work, and it worked WONDERFULLY. It was easy, quick, and surprisingly compatible. Once I managed to wrap my mind around your solution, it was surprisingly simple. Suddenly “position: relative” makes sense to me (and I’ll be using it for every #container I create from now on).
So thanks, you’ve saved my butt today.
What about when u want to have a footer appear below these “position: absolute” columns?
Doing a “clear:both” doesn’t work.
first off, thank you so much, this is a beautiful fix to a constant problem for me.
secondly though, it throws things completely out of whack in safari, and I can’t think for the life of me how to fix it.
any help would be greatly appreciated, thanks,
What happens in Safari then?
I’m having trouble with both relative and margin:0 auto; to work together to center the page. I’ve always seen that margin:auto and relative positioning were incompatible.
Right now I’m using the absolute position at 50% then a negative margin of half my width, but of course I ran into the problem of when the window is scaled down or when running at 800×600 resolution, I cannot scroll to the top and left due to the negative margin. any help is welcome, the work site I’m working on to fix the problem is http://www.ayaconcepts.com/brmt2/
never mind, rookie mistake =p. didn’t set my .wrapper width and height.
thanks a lot!!!
now…about vertical centering =D… haha
the journey never ends!
Well glad I could help!
Here are some “struts & springs” examples that may help people with vertical centering, fixed size gutters, etc.
.container {
position: relative;
margin: 20px auto;
background: #ff9999;
border: 4px solid green;
height: 30%;
}
#leftstuff {
position: absolute;
left: 10px;
top: 20px;
height: 50px;
background: #999999;
border: 1px solid black;
}
#middlepin {
position: absolute;
left:0%;
right: 50%;
}
#middlestuff {
position: absolute;
left: 80px;
right: 5px;
top: 25px;
background: #999999;
border: 1px solid black;
}
#rightstuff {
position: absolute;
left: 50%;
right: 10px;
bottom: 0px;
top: 0%;
background: #999999;
border: 1px solid black;
}
#centerpin {
position: absolute;
top: 0px;
bottom:50%;
border: 2px solid red;
}
#middlestuff2 {
position: absolute;
bottom: –25px;
height: 50px;
background: #999999;
border: 1px solid black;
}
blah
blah
blah
left blah, blah
middle blah, blah
right blah, blah
blah
blah
middle blah, blah
ok, well so much for that. Let’s try pre:
.container {
position: relative;
margin: 20px auto;
background: #ff9999;
border: 4px solid green;
height: 30%;
}
#leftstuff {
position: absolute;
left: 10px;
top: 20px;
height: 50px;
background: #999999;
border: 1px solid black;
}
#middlepin {
position: absolute;
left:0%;
right: 50%;
}
#middlestuff {
position: absolute;
left: 80px;
right: 5px;
top: 25px;
background: #999999;
border: 1px solid black;
}
#rightstuff {
position: absolute;
left: 50%;
right: 10px;
bottom: 0px;
top: 0%;
background: #999999;
border: 1px solid black;
}
#centerpin {
position: absolute;
top: 0px;
bottom:50%;
border: 2px solid red;
}
#middlestuff2 {
position: absolute;
bottom: –25px;
height: 50px;
background: #999999;
border: 1px solid black;
}
blah
blah
blah
left blah, blah
middle blah, blah
right blah, blah
blah
blah
middle blah, blah
ok, never mind
Exactly what I was looking for! Very clever and it works perfectly. Combining this with appropriate use of em values, I was able to make my entire page scalable for visitors that are visually impaired. The only thing that was remaining was a text overlay I had over an image…and thanks to your clever work, it turned out perfect! Thanks!
This is great stuff. Thanks a lot.
Glad to hear it!
I’ve just worked through a problem with this approach, which led me to go back to the old way (see below)…
The problem is that, when all the page content is contained within the “wrapper” 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 forcing Firefox to treat the end of the document as the end of the body! (I got it to work in Internet Exploder though!!)
Only a problem if you want a bottom-aligned image, it seems..
So, I’ve resorted to this:
body{
background:#f9f9f9;
background-image:url(images/bg_body.gif);
background-position:bottom left;
background-repeat:repeat-x;
text-align:center;
}
#wrapper {
width:772px;
margin:0 auto;
text-align:left;
}
Does the wrapper go on the .css file or in the css area of the page
With CSS that doesn’t matter. You can put it anywhere you like!
This solution sounds like it should work great and I can see that others have used it successfully. I have copied the code exactly as you wrote it and it simply will not work. I know I may simply be overlooking the obvious. I have tried adjusting the width from auto to 100% and also changing my DIVs from ID to Class since that is how you wrote it. None of this seems to work. I was wondering if perhaps the type of rollover I am using (shifting a multipart image) may be the problem. I really am at a loss but I would like to use your solution and am trying to solve this problem before I add any php or code to the page. Any help is appreciated. http://www.humdilly.com/humdilly/events/cats.php
I forgot to mention I am using Mozilla and have tried it in IE6 as well with no luck.
Forgive my series of responses here but I did manage to get it to work (not perfectly tho) when I put in a width pixel range between 400 and 800. It did not work when I tried 1200px tho. Very strange.
Excellent. Why ever did they remove the float option in CSS :(
Interesting, will try it on my site, if it works, i’ll give a reply.
Mark: Remove what float option? Of course Floating still works in CSS!
Milo: Hope you manage it!
Worked for me! Thanks!
Just exactly what I needed to know — saved me hours of tinkering. I suspect that I’ll be using this solution a lot — thanks!
How did you make the div go OVER the flash again? Flash wants to stay on top for me.
By adding “z-index:5;” to your rules for #content. (In this example)
This is a wonderful solution. I just have a couple of caveats:
1. I need this to work consistently in FireFox, IE 6+, and Safari with a Flash element…
2. The Flash fix is great (using the z-index), but I’m trying to position a DHTML generated flyout menu over the Flash with this method. The positioning is fine, but the menu flyouts (sub’s) are a bit wonky. Your solution works beautifully in FireFox, haven’t been able to test it in IE yet, but in Safari the menu flyouts “vibrate” when crossing over the Flash. Is there anyway to fix this? I can’t ignore the Safari people…they comprise appx 15% of the visitors to my site…
FYI…the DHTML menu I’m considering using is from TwinHelix: http://www.twinhelix.com/dhtml/fsmenu/
Just an update to my last message…with this positioning method the DHTML menu over Flash works beautifully in IE & FireFox on a PC. But, still need to solve the Safari issues for a Mac…
Cy: You should be able to get them working by adding z-index:5; (the number refering to a layer higher than the Flash content) to your submenu 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 message. 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 trappings of Safari.
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 website (www.adobe.com). They are trying to do the same thing (run a menu over the Flash). Works well in everything but Safari…
Ideas? :) Thanks!
Eh? Try giving the menus a value above Flash. (Since you want the submenu’s over the Flash, right?)
Tried that already…the menu opens behind the Flash…which I don’t want it to do… Ideas?!? :)
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.
You have put “[param name=“wmode” value=“transparent”] ” in your html for the flash object, right? (or opaque instead of transparent)
Yes, I have it set to ‘transparent’. For kicks, I also tried ‘opaque’ and it made no difference…
Your best bet is a bit of JavaScript. Veerle’s got an article on it: Experimenting with Flash Content and z-index
Hi! :)
Thanks for the information, very helpful! :)
now… just got to fix the other IE problems that I am having… hope it’s just the z-index around the wrong way…
Is it easier/better to create a page for IE or fix it for IE last?
It’s far easier (eventually) 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* something with a lower z-index.
Hi James,
Thanks for the information. The problem was the divs had to be 100% height (and a couple of other little things) to look correct — I just assumed that it was the z-index as it looked like another div was covering it up.
Now I’ve got to look into having a seperate style sheet for printing the page, which sounds like fun! :)
Must create for IE last… Else code gets mucky… Must learn from this mistake… MUST REMEMBER!!!! :)
Ran accross your centering DIV info today. Been looking FOREVER for a way to keep centered content from “exiting left” when the browser window was less wide then the content…
Your way is THE BEST!
Thanks.
This is very helpful but at the same time as centering this DIV i need to also make it 100% height. So the relative wrapper kills my idea in this case.
Similar to what Sandra is trying to do i think!
Any thoughts?
Yes, sadly “position:relative;” does kill that. The only way to get (minimum) 100% properly 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 support it.
The other way is to give the #content a “position:fixed” & “height:100%”, and to have the other content scroll under it. Depending on your design this may look really cool or really awful.
This is, however, the oldest problem of CSS, so you might better helped by looking up a ready-made CSS page with 100% height, and applying what you’ve learnt here to that.
Good luck Anton & Sandra!