Horisontal CSS Centering for Absolute Positioning

A new and better way to center your elements horisontally has been found. Read all about it on AkaXakA’s website.

In my daily work, I needed to center a div horisontally. Usually this is easy. Not so when using absolute positioned elements.

Basically, absolute positioning allows you to type in coordinates for your div, coordinates from the top-left of the screen.

I found the following solution to work fairly well, and I’m posting it here in case someone else might gain from it, as well as a reminder to myself.

Give then Take

If you need to center your absolutely positioned #content div, wrap it in a new #content-container div and apply the following CSS.

#content-container {
	width: 500px;
	position: absolute;
	left: 50%;
}
#content {
	position: absolute;
	left: -250px;
}

This will move the #content-container div‘s left side to the exact center. After that, the #content div will be moved half the width of the #content-container div‘s width to the left, thereby centering it.

It works reasonably well in both Mozilla and IE, as long as the browser is larger than the centered content.

Update: Doesn’t work as well as I initally thought. If scale the browser to be smaller than the the width of the #content-container, it’ll bork. Suggestions are welcome.

Update: AkaXakA‘s method is better. Read it in the comments.

Feel free to post your solutions in the comments.

49 thoughts on “Horisontal CSS Centering for Absolute Positioning”

  1. AkaXakA says:

    The method I use is to have a wrapper div with the following css:

    .wrapper {

    position:relative;

    margin:0 auto;

    text-align:left;

    }

    (with the IE fix thrown in for good measure:

    body{text-align:center;} )

    And then the content can be absolutely positioned using the wrapper as reference point. This means you can still use absolute positioning while centering the whole page, like so:

    #content {

    position: absolute;

    left: whatever;

    top: whatever;

    }

    Or isn’t this what you meant?

  2. Jonas Rabbe says:

    Just out of curiosity, why do you want to position the div absolutely if you want it centered. The only thing I can think of, is that you want it a set distance down from the top, this could have been achieved by putting an element above the div with the desired height.

    2?

  3. Joen says:

    Hmmm..

    That does work.

    I wonder if it was position:relative; on the wrapper that did the trick?

    Thanks for your help! I’ll update the article when I get some spare time!

  4. Joen says:

    Jonas,

    In this specific case, I needed a div to be placed OVER some Flash content.

    It seems to work with Aka’s solution.

  5. m^r(oS says:

    I really don’t like to use ‘position’ it is so compliccated and it always gets broken in one way or another.

    What i do instead is the following….

    ??Create a Container with overflow:auto;

    ??Float everything inside that div (is better if everything is floated to the same side)

    ??Add a closing div (footer) and add clear:both;

    If you want a working example check out the css of the wp theme i’ve made (equiX), there i’m using this method.

  6. AkaXakA says:

    I wonder if it was position:relative; on the wrapper that did the trick?

    When you apply position:relative; to an element, every element inside it will use it’s parent as reference, not the viewport. You could say it resets the reference point of it’s children elements.

  7. Joen says:

    When you apply position:relative; to an element, every element inside it will use it?s parent as reference, not the viewport. You could say it resets the reference point of it?s children elements.

    Fantastic. Thanks a lot.

  8. Tristan says:

    Very slick! I’ll have to add this to my CSS tricks bookmark folder.

    I’ve definately used that position:relative trick before; it’s good to know if you ever want to nest absolutely-positioned elements like this.

  9. I’d like to correct what you wrote:

    “Basically, absolute positioning allows you to type in coordinates for your div, coordinates from the top-left of the screen.”

    Strictly speaking, this is wrong.

    It’s actually from the top left of the elements positional parent.

    The elements positional parent is the first parent element up the hierarchy that has either position: relative or position: absolute.

    I often include this in my CSS if I am to use absolute positioning, because it makes all div tags positional parents:

    div {

    position: relative;

    }

    Note that this has no other effect (that I know of) as long as you don’t also set the top and left attributes for the element.

  10. I skimmed the comments before writing, but I see AkaXakA said something to that effect already.

  11. AkaXakA says:

    Thanks for the link Joen, and thanks to Brian for the acknowledgement.

  12. Brent says:

    Thanks for the code above. Quick question…

    What if our DIV with the .wrapper class (refering to AkaXakA’s code above) has a background color that we want to continually sit behind all child DIVs?

    Or, in other words, is there a way to get the .wrapper class DIV to dynamically increase in height as a function of its children?

    Going back to basic HTML, this is easy:

    Ever-changing volumes of content here…

    Is there a CSS-only solution that achieves the same functionality while holding constant the DIV-centering functionality AkaXakA referenced above?

  13. Brent says:

    Let’s try that last part again:

    Going back to basic HTML, this is easy:

    Ever-changing volumes of content here…

    Is there a CSS-only solution that achieves the same functionality while holding constant the DIV-centering functionality AkaXakA referenced above?

  14. AkaXakA says:

    The wrapper does increase it’s height when it’s children do.

    If I recall correctly you just give a width to the wrapper and all should be fine.

    However, your question reads a bit strangely. Maybe a drawing would help 🙂

  15. Patrick says:

    ALL the shyt i read in here does not work. Its impratically wrong , wrong , wrong , wrong … Absolute DIV are developed on a seperate layer to all static Elements. You can not nest an absolute DIV !!! in another DIV thats relative or even absolute.

    Go ahead and waste time and effort. Cross browser testing will decapitate your hopes.

    Div in absolute positioning are like wild pigs they do what they want, you can’t control them by trying to align it with a another centred element ((( margin: 0 auto )))…. does not work. Wasted time on this as you can tell already …

    Hmmm only way you can get an absolute div to be correctly centred with other static elements ie and

    is if your use a client side script ie. JAVASCRIPT …. obtain the window screen size then do a ratio with the screen size of your editorial software ie DREAMWEAVER… and manually realign the coordinates ( top & left ).

  16. paul says:

    Check this out

    Basically using a negative value for your top and left margin lets you set the origin of the object in question to it’s centre. Then simply use the left and top at 50% to put your element right in the page.

    #content { /* some content of width 500px */

    position: absolute;

    margin-left: -250px;

    left: 50%;

    }

    Works in IE & Firefox. I’ve not got anything older to hand. If you find it doesn’t work then please drop me a mail to let me know.

  17. Aarohi Johal says:

    OK, that works. But what if its a piece of text that we need to center? We can’t possibly have any idea of what pixel size that is.

    Any ideas?

  18. paul says:

    Try specifying the width of the div in em rather than px and the margin as minus half that value also in em.

    You will need to specify the font size on the div so that it is calculating the em size based upon the contents of the box and not the font-size that it has inherited.

    Try it and post back the results – I haven’t tried it myself, and I’ve not got the time right now.

  19. Aarohi Johal says:

    It works. Thanks a lot paul 🙂

    content

    {

    position:absolute;

    left:50%;

    top:whatever;

    display:block;

    width:10em;

    height:10em;

    margin:0 -5em;

    font-size: 2em;

    text-align:center;

    }

  20. paul says:

    Great!

    I was just going to warn you quickly about setting font sizes with em – it can be a wonderful tool, and it can also be seriously confusing. When you set a font size based on em it bases it on then current font size.

    This means that if you set the font size to be 2em within a div that is 1.5em then it will appear at a different size to a font at 2em within a div that is 1em (presuming that both divs are working on the same defaults)

    This is great because you can set a base font size and then cascade everything off it so that all you need to do is change the base size and the whole document follows.

    I hope that makes sense

  21. Will says:

    Thank you so much for the article, Brian, and the solution, AkaXakA!! It all worked for me once I specified a width for my .wrapper div. Works in both Firefox and IE6.

    Stangely, if I put a border on the wrapper, it makes a stretchy full width line across the top of the screen in Firefox (with no height) while in IE it puts a border around the whole page, including the scroll bar. I would’ve guessed the border would be 800px, the width I specified for the wrapper. [Sorry if that made no sense. It don’t really matter. Gratitude was my point.]

  22. Joen says:

    I’ve been quietly looming over this discussion, and I would just like to point out how fantastic it is that all these great solutions have emerged. My thanks to you all.

  23. AkaXakA says:

    I’m getting so many clickbacks that I shoudl simply write an article about it as not to disapoint people…hmm.

  24. Joen says:

    AkaXakA, please do! And send me a track / pingback will you? That way people somehow stumbling into this will find a solution.

  25. Josh says:

    Thanks guys, I was using a different trick, but these work really well!

  26. Joen says:

    Thanks AkaXakA, updated the trackback and the article.

  27. Aurule says:

    Here’s a bit of a spinoff on this. How about centering a div whose size you can’t predict at all? I’m specifically thinking of a title div that has to hold text and will change its size based on that text. Is there any way to do this other than going through and manually divining the proper sizes?

  28. Aurule says:

    Actually, I should be a bit more specific. The title class is applied to divs that serve as titles for news articles, so there’s more than one on a page. I was a bit ambiguous about that in the other post.

  29. Set the height in em’s if you know the title is going to be one line.

  30. Aurule says:

    Well, the height wasn’t a problem, it was the width. I did figure it out, though. Instead of using divs, I used spans to encase the titles and that let me use the margin trick to center it. Not sure how portable this is or how well it’d work for other uses, but it was enough for me. Maybe wrapping the div inside a span would make it more useful? That is, if you can even do that in proper (x)html :p

    Thanks all,

    Aurule

  31. Donethat says:

    AkaXakA said:

    The method I use is to have a wrapper div with the following css:
    .wrapper {

    position:relative;

    margin:0 auto;

    text-align:left;

    }

    (with the IE fix thrown in for good measure:

    body{text-align:center;} )

    And then the content can be absolutely positioned using the wrapper

    as reference point. This means you can still use absolute positioning

    while centering the whole page, like so:

    #content {

    position: absolute;

    left: whatever;

    top: whatever;

    }

    Or isn?t this what you meant?

    Well I have built a site using both tables and div’s. The reasons are historic. I have tried using the margin: 0 auto; method with absolutley no success. I even made a really simple page with a single div and a linked syle sheet and it still didn’t work. In explorer the div became glued to the right side of the window. The give and take method does seem to work well but you say that using the method quoted is better…..why?

    All the best

    Donethat

  32. I should have mentioned that you need to specify a width for the contentbox.

  33. Donethat says:

    There must be something else I’m doing wrong.

    I love your give and take method, it works without effecting the content, haven’t found the downside yet though I’m sure there is one.

    Donethat

  34. The give and take method goes a bit wonky when the window is smaller than the size of the wrapper – and if you work with percentages or em’s for your width you tend to get rounding errors.

  35. Donethat says:

    Haven’t had that problem yet.

    When I have a little more time I shall play with the various methods.

    Thanks for your contributions.

    Donethat

  36. Michael Johnston says:

    Wow, reading the comments here solved a huge number of problems I was having with css layout. For example, valign is as simple as:

    #container {

    position: relative;

    }

    #bottom {

    position: absolute;

    bottom: 0px;

    top: 0%;

    }

    similarly, using a container with position: relative/absolute and children with position: relative, the traditional struts & springs style of layout is possible, which I had not previously realized.

  37. Donethat says:

    Micheal

    Can you please show me how the HTML for this might work and have you tried it in IE yet?

    Take care

    Donethat

  38. Lina says:

    I run the following, that is tested on IE, Firefox and Opera:

    body{

    margin: 0px;

    }

    DIV#container{

    position: absolute;

    margin-right: auto;

    margin-left: auto;

    top: 0px; your content

    Note however that this will cover any content on both sides of #content.

    Example of this is http://www.evasunderklader.se. It’s the top bar that is formatted with the above.

  39. Lina says:

    Oops… the above was incomplete. Lets try again:

    body{

    margin: 0px;

    }

    DIV#container{

    position: absolute;

    margin-right: auto;

    margin-left: auto;

    top: 0px; whatever you want

    left: 0px; VERY important

    width: 100%; VERY important

    }

    DIV#content {

    width: 881px; free of choice

    margin-right: auto;

    margin-left: auto;

    text-align: center;

    }

    the HTML is:

    your content

    Note however that this will cover any content on both sides of #content.

  40. Harley C. Dangan says:

    OMG! I was having this alignment problem with absolute divs for days! This really helped me a lot!!!

    Cheers to you!

  41. Chad says:

    I’m centering a transparent png logo on top of my header page using the absolute positioning. You have the right method, for the #content just replace the “px” with an elastic “em” and it will work both on IE and Firefox. It works absolutely fine on mine.

    Thanks and more power!!

  42. Spirt Bear says:

    Thanks so much. Lina’s code did the trick for me to enable me to display some progress bars that appear while a simulation is crunching away, than using the code I could cover up those progress bars once the simulation was finished and results could be displayed as if a new page is being rendered.

  43. Dr Evil says:

    What’s all the fuss about? Can’t you just put everything in a absolutely positioned , set it to 100% width then centre the div contents.

    I’ve not tested that sample but I’m sure it’s worked for me before.

  44. Gente Fina says:

    You are the man… worked perfectly… thanks

  45. Roald says:

    Thanks.. it worked perfectly for me! I used it on my webdesign portfolio, on the top..

  46. Steeve Gauthier says:

    Thanks for the idea. I have modified the code to be able to center a table and still use absolute positioning, (relative to the center of the table then…)
    #contenant
    {
    width:500px;
    position:absolute;
    left:50%;
    }
    #la_table
    {
    position:absolute;
    top:0px;
    height:1200px;
    left:-100%; See the minus here.
    background-color:white;
    }
    h1.item
    {
    top: 200px;
    left:-300px; See the minus here.
    }
     
    HTML looks like this:
    <div id=contenant>
    <TABLE id=la_table border=2> (tr td…)
    <h1 class=item>(input type=xx, textarea, button etc.)</h1>
    </table></div>
     
    With this I am able to zoom in and out, print the page and have a background picture behind the table.
    Still, it does NOT show the same result with IE8 versus FF 3.5. Elements are positionned the way I want in FF, but relative point will be left of the table in IE not the center and this, I don’t know why.

Comments are closed.