Absolute Horizontal And Vertical Centering In CSS

Advertisement

We’ve all seen margin: 0 auto; for horizontal centering, but margin: auto; has refused to work for vertical centering… until now! But actually (spoiler alert!) absolute centering only requires a declared height*1 and these styles:

.Absolute-Center {
  margin: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

I’m not the pioneer of this method (yet I have dared to name it Absolute Centering), and it may even be a common technique, however, most vertical centering articles never mention it and I had never seen it until I dug through the comments section of a particular article2.

There, Simon3 linked to this jsFiddle4 that blew every other method out of the water (the same method was also mentioned by Priit5 in the comments). Researching further, I had to use very specific keywords to find some6 other7 sources8 for this method.

Having never used this technique before, I put it to the test and discovered how incredible Absolute Centering really is.

Leave a comment on CodePen129, Smashing Magazine10, or message @shshaw11 on Twitter if you have any additional features or suggestions.

Find additional demos, a comparison table, and more on CodePen129.

Advantages:

  • Cross-browser (including IE8-10)
  • No special markup, minimal styles
  • Responsive with percentages and min-/max-
  • Use one class to center any content
  • Centered regardless of padding (without box-sizing!)
  • Blocks can easily be resized
  • Works great on images

Caveats:

  • Height must be declared (see Variable Height13)
  • Recommend setting overflow: auto to prevent content spillover (see Overflow14)
  • Doesn’t work on Windows Phone

Browser Compatibility:

Chrome, Firefox, Safari, Mobile Safari, IE8-10.
Absolute Centering was tested and works flawlessly in the latest versions of Chrome, Firefox, Safari, Mobile Safari, and even IE8-10.

Explanation

After researching specs and documentation, this is my understanding of how Absolute Centering works:

  1. In the normal content flow15, margin: auto; equals ‘0’ for the top and bottom.
    W3.org16: If ‘margin-top’, or ‘margin-bottom’ are ‘auto’, their used value is 0.
  2. position: absolute; breaks the block out of the typical content flow, rendering the rest of the content as if that block weren’t there.
    Developer.mozilla.org17: …an element that is positioned absolutely is taken out of the flow and thus takes up no space
  3. Setting top: 0; left: 0; bottom: 0; right: 0; gives the browser a new bounding box for the block. At this point the block will fill all available space in its offset parent, which is the body or position: relative; container. Developer.mozilla.org1918: For absolutely positioned elements, the top, right, bottom, and left properties specify offsets from the edge of the element’s containing block (what the element is positioned relative to).
  4. Giving the block a width or a height prevents the block from taking up all available space and forces the browser to calculate margin: auto based on the new bounding box. Developer.mozilla.org1918: The margin of the [absolutely positioned] element is then positioned inside these offsets.
  5. Since the block is absolutely positioned and therefore out of the normal flow, the browser gives equal values to margin-top and margin-bottom centering the element in the bounds set earlier.
    W3.org20: If none of the three [top, bottom, height] are ‘auto': If both ‘margin-top’ and ‘margin-bottom’ are ‘auto’, solve the equation under the extra constraint that the two margins get equal values. AKA: center the block vertically

Absolute Centering appears to be the intended use for margin: auto; based on the spec and should therefore work in every standards compliant browser.

TL;DR: Absolutely positioned elements aren’t rendered in the normal flow, so margin: auto; centers vertically within the bounds set by top: 0; left: 0; bottom: 0; right: 0;.

Within Container

.Center-Container {
  position: relative;
}

.Absolute-Center {
  width: 50%;
  height: 50%;
  overflow: auto;
  margin: auto;
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

With Absolute Centering, you can place your content block inside of a position: relative container to align the block within the container!

The rest of the demos will assume these styles are already included and will provide add-on classes to implement various features.

Absolute Center,
Within Container.

This box is absolutely centered, horizontally and vertically, within its container using
position: relative

Within Viewport

.Absolute-Center.is-Fixed {
  position: fixed;
  z-index: 999;
}

Want the content block centered in the viewport? Set it to position: fixed and give it a high z-index, like the modal on this page.

  • Mobile Safari: The content block will be centered vertically in the whole document, not the viewport, if it is not within a position: relative container.

See the Modal Demo page.21

Offsets

.Absolute-Center.is-Right {
  left: auto; right: 20px;
  text-align: right;
}

.Absolute-Center.is-Left {
  right: auto; left: 20px;
  text-align: left;
}

If you have a fixed header or need to add other offsets, simply add it in your content block’s styles like top: 70px;. As long as margin: auto; is declared, the content block will be vertically centered within the bounds you declare with top left bottom and right.

You can also stick your content block to the right or left while keeping it vertically centered, using right: 0; left: auto; to stick to the right or left: 0; right: auto; to stick to the left.

Vertical Center,
Align Right.

This box is absolutely centered vertically within its container, but stuck to the right with
right: 0; left: auto;

Footnotes

  1. 1 http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/2#Height
  2. 2 http://designshack.net/articles/css/how-to-center-anything-with-css
  3. 3 http://designshack.net/articles/css/how-to-center-anything-with-css/#comment-684580538
  4. 4 http://jsfiddle.net/mBBJM/1/
  5. 5 http://designshack.net/articles/css/how-to-center-anything-with-css/#comment-684580409
  6. 6 http://www.vanseodesign.com/css/vertical-centering/
  7. 7 http://www.student.oulu.fi/~laurirai/www/css/middle/
  8. 8 http://blog.themeforest.net/tutorials/vertical-centering-with-css/
  9. 9 http://codepen.io/shshaw/details/gEiDt
  10. 10 http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/#comments
  11. 11 http://twitter.com/shshaw
  12. 12 http://codepen.io/shshaw/details/gEiDt
  13. 13 http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/2#Height
  14. 14 #Overflow
  15. 15 http://taligarsiel.com/Projects/howbrowserswork1.htm#Layout
  16. 16 http://www.w3.org/TR/CSS2/visudet.html#normal-block
  17. 17 https://developer.mozilla.org/en-US/docs/Web/CSS/position#Absolute_positioning
  18. 18 https://developer.mozilla.org/en-US/docs/Web/CSS/position#Notes
  19. 19 https://developer.mozilla.org/en-US/docs/Web/CSS/position#Notes
  20. 20 http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-height
  21. 21 http://s.codepen.io/shshaw/fulldetails/gEiDt#Fixed

↑ Back to top Tweet itShare on Facebook

A passionate front-end developer who cares about CSS, JavaScript and keeping code clean and nifty.

Advertising
  1. 1

    Say I wanted to vertically center content where I have an image on the left and text on the right.

    Is there I way I could do that?

    Would it be a case of using the above techniques, but setting the width of the two bits of content?

    I ask as it would save having to repeat parts of css just to allow for different sized elements that fit within.

    Apologies if this is a question that seems dumb, I come from a print background and I am currently self teaching web design.

    0
  2. 154

    This is fantastic. Very thorough. Thank you :-)

    1
  3. 205

    It looks like absolute centering the image will not work if the image height exceeds the container. We could clip with overflow set to hidden, however if we want the image to scale with it’s container, simply setting the max-width to 100% doesn’t seem to work either.

    Here’s the pen I set up:
    http://codepen.io/nataliecodes/pen/yxeqG

    0
    • 256

      Natalie,

      It does work, however it overflows the container top & bottom equally :-) The problem is you can’t just set `max-height: 100%` to resize the image to the container without `width: 100%` causing some nasty resizing.

      The best option here would be to set the image as a `background-image` on an extra element and use `background-size: contain` to scale it to the smallest side. This is a quick example based on your CodePen:
      http://codepen.io/shshaw/pen/IAfms

      You can keep the image itself in the code and just hide it with `visibility: hidden` for better accessibility. Technically, you could put the `background-image` on the container and avoid having extra markup, but having the extra element allows you to set the image sizing more precisely ( `max-height: 90%` relative to the container, for instance!)

      Hope that helps!

      1
  4. 307

    Hi Stephen,

    This *new* solution seem works well for resize function, but i dont think it’s too necessary. The inline-block solution are working with whatever the block width/height is. So i think the inline-block solution’s better, but not your way. I dont know if anyone else used the same way of mine, but i think it’s working well even on IE7. And we also dont need to care about the font, long content etc.

    http://jsfiddle.net/y5V74/

    I used a position div with width = 0 and height = 100% with display-inline: block to do it. For IE using the old school hack: *display: inline; zoom: 1

    At the moment, i’ve not found any bug from it yet for our project :)

    -1
    • 358

      Yes, `inline-block` has quite a bit of flexibility, but does require some setup. Not quite as easy to drop-in. If you don’t need to support IE7, then you can use `:after` like in the examples above, instead of a separate element, making it a little easier to use almost anywhere.

      However, the main issue with `inline-block` is you have to compensate for spacing. In your example, the block is not actually centered horizontally, it’s generally off by around 5-10px depending on your font and letter-spacing. In my examples, I use `margin-left: -0.25em` on the `:after` element. You also have to specify a width on the centered element smaller than 100% minus the spacing so that it doesn’t bump the `height: 100%` element down to the next line.

      Other than that, `inline-block` is pretty great!

      0
      • 409

        Hi,

        Yah the problem’s only that we need to insert a position div next to it, but actually it’s working well for me in almost case. Must retest on the font size’s not good solution, i forgot to insert the solution to solve that inline-block issue on the example, you can check it again:

        http://jsfiddle.net/y5V74/1/

        Set the font-size, word-spacing, letter-spacing to remove the space of the inline-block and font-size for the content block.

        I think it’s better for almost cases because we dont need to set width, height for the content container which we need it more on real using.

        0
      • 460

        You can solve the `height: 100%` element bump to new line using
        white-space: nowrap; on the container
        http://jsbin.com/EwELIFU/1/watch?html,css,console,output

        The problem i’ve found with that method is that when you change the dimensions of of the inner box, the whole container is getting repainted.

        0
  5. 511

    Excellent tricks! Thank you.

    0
  6. 562

    Bikram Choudhury

    October 6, 2013 7:45 pm

    Its nice. But I have a suggestion. You may list the different techniques with on-page hyperlinks lists (pointing to the respective techniques/sections) at the top. And you may suggest which works cross-browser best. If somebody dont want to go through every technique just provide him/her a quick solution. I know cases are different. Just think.

    Thanks again, your explanation is awesome.
    Bikram Choudhury
    rankingoogle.com

    0
    • 613

      Thanks, Bikram! The primary purpose of this article was to highlight this alternative technique that hadn’t received much coverage. However, I do have some of what you mentioned on the CodePen demo here: http://codepen.io/shshaw/full/gEiDt

      There you’ll find a compatibility table comparing the various techniques and what features they provide over others, along with quick links to the rundowns of the techniques. The table was a bit too big to fit in the article here, so I simply linked to it. Unless otherwise mentioned, all of the techniques work in modern browsers (Chrome, Firefox, Safari), and most are fine with IE9+, but the table will show that in detail.

      0
  7. 766

    Clap, clap, clap!

    Good article!

    0
  8. 817

    Great post thanks mate.

    0
  9. 868

    Nice post. Covers everything.

    0
  10. 919

    This might be the best css solution of all time.

    0
  11. 970

    oldest and easyest way:

    position: auto;
    left: 50%;
    top: 50%;
    margin-left: -(box width/2)px;
    margin-top: -(box height/2)px;

    0
    • 1021

      Unfortunately that doesn’t work properly with percentages because percentage margins and padding are based on the width of the container, not the height, causing the vertical offset to be wrong.

      0
  12. 1072

    he… hehe….
    hehehehe….
    HEHEHEHEHEHE…. HAHAHAHAA….
    HAAAAHAHAHAHAHAHHAHAAAAA!!!!

    I love you so much!!!

    My css code didn’t work anyway with line-height + vertical align. No way. But this… is … PERFECT!

    Thanks so much!

    -1
  13. 1123

    Without declared height, only width/max-width.

    http://codepen.io/davidhc/pen/HBzkL

    0
    • 1174

      David, `display: table` on the centered box is all that’s needed to avoid a declared height (on modern browsers). As far as I can tell, the clearfix hack isn’t doing anything, at least on Chrome.

      0
  14. 1225

    the css:
    margin: auto;
    position: absolute;
    top: 0px; left: 0; bottom: 0; right: 0;
    doesnt work in IE 11 if top declaration altered by javascript (e.g. top: -15px;), text goes to the bottom.

    0
  15. 1276

    Its always nice to know these kind of tricky things. It really helps you to explore more and more.

    0
  16. 1327

    This is fantastic, a solution I’ve been looking for for quite some time.

    However, I have one bug I can’t figure out in Safari and Chrome. I am using absolute centering to center a div that is 920px tall. On a smaller monitor, I can’t actually scroll up to the top of my page in Chrome or Safari. And if I resize my browser window even more — making it shorter — then more of the top of my site is cut off. I can scroll down just fine to see the bottom of the page, but not the top. Hope I’m describing that well enough.

    This doesn’t happen in Firefox. Any ideas? Would really appreciate some feedback, thanks!

    0
    • 1378

      Hey Jamey! That’s one of the rendering differences in Webkit and Gecko.

      Here are two options:

      * Set `max-height: 100%;` on your centered element so that it doesn’t expand past the screen’s height. Then with `overflow: scroll` your content will still be visible! DEMO: http://codepen.io/shshaw/pen/FymGE

      * Adding a media query for screen heights less than the ideal height of your div to remove `margin: auto` so that it won’t go off the top of the screen. DEMO: http://codepen.io/shshaw/pen/HGajD

      Hope that helps!

      0
  17. 1429

    excellent
    thanks!

    0
  18. 1480

    Thanks for this very well written, insightful and helpful.

    0
  19. 1531

    thanks a lot for that

    0
  20. 1582

    Man… I love you!!!!
    I’m absolute beginner and I wasted hours trying to figure out a solution without any luck, until I found your method.

    Thank you for sharing your knowledge.

    0
  21. 1633

    Just what I needed! Thank you so much!

    0
  22. 1684

    It’s good to see this collection in one site!
    But there are more annoying caveats of the table-cell method than extra markup, such as an element with display: table-cell cannot be floated and cannot has margin.
    It think (not sure) if you can’t use flexbox there are situations where no css trick will help, only javascript.

    1
  23. 1735

    Thanks man, saved my life :)

    1
  24. 1786

    How to margin: 0 auto; in details….Div on center

    bradny

    -1
  25. 1837

    You make my day. This article is very useful for me.

    Thank you!

    0
  26. 1888

    Christian Longe

    July 9, 2014 8:33 pm

    I know this is stated in the directions, but I am re-stating that width and height must be set specifically for this to work in IE.

    I set a max-width and max-height and left width and height as auto or unset. I assumed the browser would be able to calculate the size of the box based on these values. All modern browsers did center the box as expected, except for IE of course.

    It took me a bit to figure out that this was the issue. IE limited the box to the max-width specified, but it didn’t center it. It wasn’t until I specifically set a width that it centered the box even though the resulting box was of course the same size.

    Can’t wait for the end of IE.

    1
    • 1939

      Huh, I don’t remember running across this issue while I tested. What version(s) of IE did you experience this bug in?

      0
  27. 1990

    Hi,
    Thats working! There are many blogposts around the web what talking about this topic, but this is what working for me:

    height: 50%; overflow: auto; margin: auto; position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px;

    Cheers!!

    0
  28. 2041

    Dudo! it’s for only height. When i will make full body in a box when it will wrong. coz it work only for hight .Center-Container hight 400px. show again under the code but not used any height. I think can do.

    Untitled Document

    Box content

    0
  29. 2092

    Looks like you have to use fixed widths in chrome.

    0
  30. 2143

    Muhammad Imran Ghazi

    October 8, 2014 12:38 am

    Thanks, your code perfectly works for me after 4 hours browsing. Now i can sleep now :)

    1
  31. 2194

    hi,tnx
    its work very well …

    0
  32. 2245

    This is the most awesome post on centering elements…

    The Flexbox approach was most suited for us. We incorporated that into our product – http://buildwithcards.com

    Thanks Smashing Magazine..

    0
  33. 2296

    a clean and handy method~

    but the most common problem on vertical centering is the height is an unknown value and you should not hardcode a value on it

    are there any handy solution to achieve this?

    0
  34. 2347

    Hi, does anyone know the HTML5/CSS codes for this image? http://uploadpie.com/7rSI5?

    I want the photo to fall exactly in the center vertically as shown in above link.

    The current codes: http://codepen.io/anon/pen/dobPvO

    Thanks.

    0
  35. 2449

    You are literally my new personal hero!
    I had a featured area that is display height which is flexible depending on display size ( set/resizes via scripts ) and a badge that must be dead center. Works like a Dream.

    Thank you.

    0
  36. 2500

    Hi and thanks for this article! It looks great in Firefox but it’s not working for me in IE8.. (my div is not centred, it appears at the top left.) Could anyone help point out what I’ve missed please? Any advice would be much appreciated, cheers!

    ..

    Sorry, an error occurred..
    ..some message here

    .modalDialog.show {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 26em;
    height: 18em;
    margin: auto;
    z-index: 11;
    }

    .modalDialog {
    background-color: white;
    opacity: 1;
    }

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top