Categories
Code Web

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.

86 replies on “On Horizontal CSS Centering using Absolute Positioning or how Relative Positioning can rock your css.”

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 !

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,

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!

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

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!

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

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

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.

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!

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…

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!

If there were no problems, designing and developing websites would be easy… but not as fun & interesting! πŸ™‚

I did get the 100% height to work. I needed 100% height so that the background image continued to the bottom of the page. It’s working, but there is a gap at the end of the page and you scroll to see nothing but the body’s background colour. I’m going to compare the gap’s size to the padding and margin measurements and see if that’s got anything to do with it.

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

BTW: I had a different z-index problem. The logo in the top left corner has a transparent lower corner and that was covering the top of the content section, blocking the use of links and also highlighting. That’s all fixed now! πŸ™‚

Hi again,

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

Back to square one… again.

Brilliant! Thanks very much for blogging this, saved me lots of tinkering as well.

Thanks for this trick. It addresses exactly the problem I am having with creating flyout menus on a centered page design. It works like a charm in IE but I cannot get it to work in Firefox. I haven’t seen any reports of the same problem in the previous responses… so what am I missing? Any suggestions?

why is fixed positioning meant to be so good when you cannot write a paragraph of text and float and image around it. Think about it. It means its so stupid! Unless there is a way?

Well there you go, ‘annoyed’!

Dana: Glad it was of use to you.

Gary: You probably missed giving your container (the thing you’re centring) a width; that’s the most common mishap anyway πŸ˜‰

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 container). I have been experimenting with the placement of the content div either directly in the table an in td’s (with the wrapper class applied) but the same result in firefox. It all works great in IE, though. πŸ™ Here is the relevant css I am using. Any other thoughts?

.wrapper {
position: relative;
margin: 0 auto;
text-align: left;
width: 800px;
}

.wilcMenu {
position: absolute;
top: 25px;
left: 29px;
background-color:#663333;
width: 100px;
height: 20px;
z-index: 10;
color: #ffffff;
}

Ha Ha…. Spare the wrapper, spoil the child!

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

Helena: Great!

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

This is a great solution, thanks for sharing!
While implementing this CSS I was trying to place a DIV under the wrapper and found it very hard to do. The only solution I came up with was to create another DIV position:absolute; and give it top:125%; (or a value greater than 100%). The problem I encounter is that different browsers interpret the top percentage value differently and I can not get consistent positioning across different browsers on win/mac machines. Is there a solution for this?

Does anyone have the same problem as I with this in FireFox (v2.0.0.4)? It works fine if the width of the browser is a bit bigger than the wrapper, but if not it’s like the wrapper has a margin and gets “stuck” when you minimize the browser too much.

This page has that same error from my computer anyway.

I want to center the container(wrapper) div while its height should be 100% and should cover the screen area vertically… i have done something like this..
container {
background-color: #78C1FE;
height: 100%;
position: absolute;
width: 774px;
text-align:left;
}

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

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

#logoright {
float: right;
height: 150px;
position: fixed;
text-align: left;
width: 50%;
}

#content {
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 bottom of the page (please refer the properties of footer div in the css) while the content 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

Can anyone tell me how to get an image to be center and absolute at the bottom of the window? πŸ™‚

I’m having a tough time getting it, I’m pretty new at CSS πŸ™

When I position: absolute;
and bottom: 10px;

it will do it and hang out there at the bottom perfectly, but I can’t get it centered πŸ™

any help would be great!

Zach: put a “position:relative;” on its containing element (which could be the body element or some div which holds the image).

Then add “margin: 0 auto;” on the element you’re trying to get in the centre at the bottom.

That should do the trick!

Okay, I have been looking all over the internet and still have yet to find an answer to my question. I am looking to center a div, this post does show how to do it, the problem is that I also want the page wrapper/container to have a height of 100% even when the content doesn’t fill the screen. I can do this by using the position: absolute so the height: 100% has something to scale to, but when I use an absolute positioning I can no longer use the margin: 0 auto.

So, may question for the masses is this: How do you center a div element and make it’s height truly 100%? I could do this with javascript, but I’m looking 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 negative margin trick.

This solution helped really helped me!
I’d tried relative positioning, negative margins…
This one really did the trick, and I’ve been looking for this kind of solution for some time.
Thank you kindly!

Your solution appeared too simple to fix [what seemed to be] a complex problem. Boy, was I wrong! All of my problems 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

arg.. I need to center a background that is randomly chosen with a javascript script… except I want it to center horizontally so if they change the width, it will keep the image centered, but i DON’T want it to stay centered vertically… and if it does, I can’t think of how to keep my other divs at the correct heights since they are smaller and they don’t change equally :S kinda sucky cuz it seems that if I use background-position center then it goes crazy in mozilla and gets stuck at the top because mozilla requires fixed attachment… but that makes the damn vertical scroll! HALP MEH! πŸ™

Awesome post! I have read elsewhere that absolute positioning is not good for browsers that can adjust text size, as it will cause the text within the absolute divs to expand past it’s boundaries. Although I haven’t experienced this, has anyone else?

I’m looking for an alternative to using multiple floats, margins, and borders, as a way to avoid implementing several IE6 hacks. Opinions on Absolute Positioning layouts vs Float layouts would be greatly appreciated. Thanks again for the post.

[..] absolute positioning is not good for browsers that can adjust text size [..]

Happily, that’s just not true. What I think people were getting at (or confusing with) is the case where someone sets a height & width in px, and then finds that text grows beyond that. Simply not setting the height solves that, and the problem (and solution) isn’t inheritly tied to absolute positioning anyway.

[..] avoid implementing several IE6 hacks [..]

You should really avoid IE hacks completely, and use Conditional Comments (Simon Clayson’s article on targeting (different) IE (versions) is the best). This allows you to feed IE6/7/8 different margins & padding, without mucking up the rest of your code.

But to answer the underlying question of not needing to resort to different CSS for IE: The best way, still, is to avoid any margin-collapse situations, use either margin or padding on any one element. 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 problems too, even if conceptually it is superior.

I am using the text-align:center; wrapper method with absolute positioning in the content block of text but my page continues to hug the right side of the window.

Either I take out the absolute value part and the centering works, or I leave in both and get only top positioning (top:0px) and the content hugging the right…

.wrapper {
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 testing I’m using is Internet Explorer 7

You need to change “position:absolute;” a “position:relative;” for your .content, however, it’s advisable to change .wrapper to body and .content to .wrapper, as that’s essentially what you’re doing.

I’m new with CSS and am busy building my first blog template. This article helped me a lot. Thank you so much, and keep up the good work!

You’re welcome, thank you very much for your comment, it’s nice to hear that this article helped!

Comments are closed.