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;

Responsive

.Absolute-Center.is-Responsive {
  width: 60%;
  height: 60%;
  min-width: 200px;
  max-width: 400px;
  padding: 40px;
}

Perhaps the best benefit of Absolute Centering is percentage based width/heights work perfectly! Even min-width/max-width and min-height/max-height styles behave as expected for more responsive boxes.

Go ahead, add padding to the element; Absolute Centering doesn’t mind!

Absolute Center,
Percentage Based.

This box is absolutely centered, horizontally and vertically, even with percentage based widths & height, min-/max-, and padding!

Overflow

.Absolute-Center.is-Overflow {
  overflow: auto;
}

Content taller than the block or container (viewport or a position: relative container) will overflow and may spill outside the content block and container or even be cut off. Simply adding overflow: auto will allow the content to scroll within the block as long as the content block itself isn’t taller than its container (perhaps by adding max-height: 100%; if you don’t have any padding on the content block itself).

Absolute Center,
With Overflow.

This box is absolutely centered within its container, with content set to overflow.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent bibendum, lorem vel tincidunt imperdiet, nibh elit laoreet felis, a bibendum nisl tortor non orci. Donec pretium fermentum felis, quis aliquet est rutrum ut. Integer quis massa ut lacus viverra pharetra in eu lacus. Aliquam tempus odio adipiscing diam pellentesque rhoncus.

Curabitur a bibendum est. Mauris vehicula cursus risus id luctus. Curabitur accumsan venenatis nibh, non egestas ipsum vulputate ac. Vivamus consectetur dolor sit amet enim aliquet eu scelerisque ipsum hendrerit. Donec lobortis suscipit vestibulum.

Nullam luctus pellentesque risus in ullamcorper. Nam neque nunc, mattis vitae ornare ut, feugiat a erat. Ut tempus iaculis augue vel pellentesque.

Resizing

.Absolute-Center.is-Resizable {
  min-width: 20%;
  max-width: 80%;
  min-height: 20%;
  max-height: 80%;
  resize: both;
  overflow: auto;
}

You can resize your content block with other classes or Javascript without having to recalculate the center manually! Adding the resize property will even let your content block be resized by the user.

Absolute Centering keeps the block centered no matter how the block is resized. Setting min-/max- will limit the block’s size to what you want and prevent it from overflowing the window/container.

If you don’t use resize: both, you can add a transition to smoothly animate between sizes. Be sure to set overflow: auto since the block could be resized smaller than the content.

Absolute Centering is the only vertical centering technique tested that successfully supports the resize: both property.

Caveats:

  • Set your max-width/max-height to compensate for any padding on the content block itself, otherwise it will overflow its container.
  • The resize property is not supported on mobile browsers or in IE 8-10 so make sure your users have an alternate way of resizing if that is essential to user experience.
  • Combining resize and transition properties causes a delay equal to the transition time when the user attempts to resize.

Absolute Center,
Resizable.

This box is absolutely centered within its container and can be resized by the user or via Javascript.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent bibendum, lorem vel tincidunt imperdiet, nibh elit laoreet felis, a bibendum nisl tortor non orci. Donec pretium fermentum felis, quis aliquet est rutrum ut. Integer quis massa ut lacus viverra pharetra in eu lacus. Aliquam tempus odio adipiscing diam pellentesque rhoncus.

Curabitur a bibendum est. Mauris vehicula cursus risus id luctus. Curabitur accumsan venenatis nibh, non egestas ipsum vulputate ac. Vivamus consectetur dolor sit amet enim aliquet eu scelerisque ipsum hendrerit. Donec lobortis suscipit vestibulum.

Nullam luctus pellentesque risus in ullamcorper. Nam neque nunc, mattis vitae ornare ut, feugiat a erat. Ut tempus iaculis augue vel pellentesque.

Images

HTML:

<img src="http://placekitten.com/g/500/200" class="Absolute-Center is-Image" alt="" />

CSS:

.Absolute-Center.is-Image {
  height: auto;
}

.Absolute-Center.is-Image img {
  width: 100%;
  height: auto;
}

Images work too! Apply the class/style to the image itself and set height: auto; like you would with a responsively-sized image to let it resize with the container.

Note that height: auto; works for images, but causes a regular content block to stretch to fill the container unless you use the variable height technique22. It’s likely that because browsers have to calculate the height for the image rendered image, so margin: auto; ends up working as if you’d declared the height in all tested browsers.

Center Cat

Variable Height

Javascript:

/* Modernizr Test for Variable Height Content */
Modernizr.testStyles('#modernizr { display: table; height: 50px; width: 50px; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; }', function(elem, rule) {
  Modernizr.addTest('absolutecentercontent', Math.round(window.innerHeight / 2 - 25) === elem.offsetTop);
});

CSS:

.absolutecentercontent .Absolute-Center.is-Variable {
  display: table;
  height: auto;
}

Absolute Centering does require a declared height, however the height can be percentage based and controlled by max-height. This makes it ideal for responsive scenarios, just make sure you set an appropriate overflow23.

One way around the declared height is adding display: table, centering the content block regardless of content length. This causes issues in a few browsers (IE and Firefox, mainly), so my buddy Kalley24 at ELL Creative25 wrote a Modernizr test to check if the browser supports this method of centering. Now you can progressively enhance

Caveats:

This will break cross-browser compatibility. You may want to consider an alternate technique26 if the Modernizr test doesn’t meet your needs.

  • Not compatible with the Resizing27 technique.
  • Firefox/IE8: Using display: table aligns the content block to the top, but is still centered horizontally.
  • IE9/10: Using display: table aligns the content block to the top left.
  • Mobile Safari: The content block is centered vertically, but becomes slightly off-center horizontally when using percentage based widths.

Absolute Center,
Variable Height.

This box is absolutely centered vertically within its container, regardless of content height.

Other Techniques

Absolute Centering is a great solution for centering, but there are other methods that may fit more specific needs. The most commonly used or recommended methods are Negative Margins28, Transforms29, Table-Cell443630, Inline-Block4531, and now Flexbox4632. They are covered more in depth in other articles, so I’ll only cover the basics here.

Negative Margins

.is-Negative {
        width: 300px;
        height: 200px;
        padding: 20px;
        position: absolute;
        top: 50%; left: 50%;
        margin-left: -170px; /* (width + padding)/2 */
        margin-top: -120px; /* (height + padding)/2 */
}

Perhaps the most common technique. If exact dimensions are known, setting a negative margin equal to half the width/height (plus padding, if not using box-sizing: border-box) along with top: 50%; left: 50%; will center the block within a container.

It should be noted that this is the only method tested that worked as expected in IE6-7.

Advantages:

  • Works well cross-browser, including IE6-7
  • Requires minimal code

Caveats:

  • Not responsive. Doesn’t work for percentage based dimensions and can’t set min-/max-
  • Content can overflow the container
  • Have to compensate for padding or use box-sizing: border-box

Absolute Center,
Negative Margins.

This box is absolutely centered vertically within its container using negative margins.

Transforms

.is-Transformed {
  width: 50%;
  margin: auto;
  position: absolute;
  top: 50%; left: 50%;
  -webkit-transform: translate(-50%,-50%);
      -ms-transform: translate(-50%,-50%);
          transform: translate(-50%,-50%);
}

One of the simplest techniques with about the same benefits as Absolute Centering, but supports variable height. Give the content block transform: translate(-50%,-50%) with the required vendor prefixes along with top: 50%; left: 50%; to get it centered.

Advantages:

  • Variable height content
  • Requires minimal code

Caveats:

  • Won’t work in IE8
  • Need vendor prefixes
  • Can interfere with other transform effects
  • Results in blurry rendering of edges and text in some cases

Futher Resources

Read more about Transform Centering in Chris Coyier’s article “Centering Percentage Width/Height Elements”33 on CSS-Tricks.

Absolute Center,
Translate(-50%,-50%).

This box is absolutely centered vertically within its container using translate(-50%,-50%).

Table-Cell

HTML:

<div class="Center-Container is-Table">
  <div class="Table-Cell">
    <div class="Center-Block">
    <!-- CONTENT -->
    </div>
  </div>
</div>

CSS:

.Center-Container.is-Table { display: table; }
.is-Table .Table-Cell {
  display: table-cell;
  vertical-align: middle;
}
.is-Table .Center-Block {
  width: 50%;
  margin: 0 auto;
}

This may be the best technique overall, simply because the height can vary with the content and browser support is great. The main disadvantage is the extra markup, requiring a total of three elements to get the final one centered.

Advantages:

  • Variable height content
  • Content overflows by stretching the parent element
  • Works well cross-browser

Caveats:

  • Requires extra markup

Futher Resources

Read more about Table-Cell Centering in Roger Johansson’s article “Flexible height vertical centering with CSS, beyond IE7″34 on 456bereastreet.

Absolute Center,
Table/Table-Cell.

This box is absolutely centered vertically within its display: table-cell parent, which is within a display: table container.

Inline-Block

HTML:

<div class="Center-Container is-Inline">
  <div class="Center-Block">
    <!-- CONTENT -->
  </div>
</div>

CSS:

.Center-Container.is-Inline {
  text-align: center;
  overflow: auto;
}

.Center-Container.is-Inline:after,
.is-Inline .Center-Block {
  display: inline-block;
  vertical-align: middle;
}

.Center-Container.is-Inline:after {
  content: '';
  height: 100%;
  margin-left: -0.25em; /* To offset spacing. May vary by font */
}

.is-Inline .Center-Block {
  max-width: 99%; /* Prevents issues with long content causes the content block to be pushed to the top */
  /* max-width: calc(100% - 0.25em) /* Only for IE9+ */
}

By popular demand: Inline-Block centering. The basic idea is using display: inline-block, vertical-align: middle and a psuedo element to center your content block inside of a container. The concept here is best explained in this CSS-Tricks article, Centering in the Unknown35. My implementation has a few new tricks here that I haven’t seen elsewhere that help solve a few issues.

The content block’s width must be declared to be no wider than 100% of the container minus 0.25em if the content is wider than the container. like a block with long paragraph text. Otherwise, the content block will be pushed to the top, which is the reason for using :after. Using :before caused the content to be pushed down 100%!

If your content block needs take up as much available horizontal space as possible, you can add either max-width: 99%;, which works for bigger containers, or max-width: calc(100% - 0.25em) depending on the browsers you support and the width of the container.

The benefits are mostly the same as the Table-Cell443630 technique, but I initially left this method out because it’s very much a hack. Regardless, browser support is great and it proves to be a popular technique.

Advantages:

  • Variable height content
  • Content overflows by stretching the parent element
  • Works well cross-browser, and can be adapted for IE7 support (view the CSS37 to see)

Caveats:

  • Requires a container
  • Relies on margin-left: -0.25em; to horizontally center correctly, but may need to be adjusted for different fonts/sizes
  • Content block’s width must be declared to be no wider than 100% of the container minus 0.25em.

Futher Resources

Read more about Transform Centering in Chris Coyier’s article “Centering In The Unknown”38 on CSS-Tricks.

Absolute Center,
Inline-Block.

This box is absolutely centered vertically using display: inline-block, vertical-align: middle and a psuedo element.

Flexbox

.Center-Container.is-Flexbox {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: center;
     -moz-box-align: center;
     -ms-flex-align: center;
  -webkit-align-items: center;
          align-items: center;
  -webkit-box-pack: center;
     -moz-box-pack: center;
     -ms-flex-pack: center;
  -webkit-justify-content: center;
          justify-content: center;
}

The future of layout in CSS, Flexbox is the latest CSS spec designed to solve common layout problems such as vertical centering. Smashing Magazine already has a great article on Centering Elements with Flexbox39 that you should read to for a more complete overview. Keep in mind that Flexbox is more than just a way to center, it can be used for columns and all sorts of crazy layout problems.

Advantages:

  • Content can be any width or height, even overflows gracefully
  • Can be used for more advanced layout techniques.

Caveats:

Futher Resources

Read more about Flexbox Centering in David Storey’s article “Designing CSS Layouts With Flexbox Is As Easy As Pie”42 on Smashing Magazine.

Absolute Center,
Flexbox.

This Flexbox box is absolutely centered vertically within its container.

Recommendations

Each technique has their advantages. Which one you choose mainly boils down to which browsers you support and what your existing markup looks like, but use the comparison table43 to make the right choice to match the features you need.

Absolute Centering works great as a simple drop-in solution with no-fuss. Anywhere you used Negative Margins before, use Absolute Centering instead. You won’t have to deal with pesky math for the margins or extra markup, and you can size your boxes responsively.

If your site requires variable height content with the best browser compatibility, try out the Table-Cell443630, Inline-Block4531 techniques. If you’re on the bleeding edge, give Flexbox4632 a try and reap the benefits of its advanced layout techniques.

(vf)

Footnotes

  1. 1 #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 #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
  22. 22 #Height
  23. 23 #Overflow
  24. 24 http://stackoverflow.com/users/2539605/kalley
  25. 25 http://ellcreative.com
  26. 26 #Other
  27. 27 #Resizing
  28. 28 #Negative-Margins
  29. 29 #Transforms
  30. 30 #Table-Cell
  31. 31 #Inline-Block
  32. 32 #Flexbox
  33. 33 http://css-tricks.com/centering-percentage-widthheight-elements/
  34. 34 http://www.456bereastreet.com/archive/201103/flexible_height_vertical_centering_with_css_beyond_ie7/
  35. 35 http://css-tricks.com/centering-in-the-unknown/
  36. 36 #Table-Cell
  37. 37 http://codepen.io/shshaw/pen/gEiDt
  38. 38 http://css-tricks.com/centering-in-the-unknown/
  39. 39 http://www.smashingmagazine.com/2013/05/22/centering-elements-with-flexbox/
  40. 40 http://css-tricks.com/using-flexbox/
  41. 41 http://css-tricks.com/does-flexbox-have-a-performance-problem/
  42. 42 http://www.smashingmagazine.com/2013/05/22/centering-elements-with-flexbox/
  43. 43 http://codepen.io/shshaw/full/gEiDt#Comparison-Table
  44. 44 #Table-Cell
  45. 45 #Inline-Block
  46. 46 #Flexbox

↑ Back to topShare on Twitter

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

Advertising
  1. 1

    This is a mystic quest for lot’s of webdesigner !
    Thanks for sharing those informations.

    2
  2. 3

    Guides like this saves a lot of time. Unfortunately CSS is not as intuitive as it should be.

    4
  3. 4

    I was overwhelmed with the urge to try this out as soon as I saw it. Ten minutes later, I have this: http://instadesign.co.uk/absolutcenter/

    Thanks so much, I shall not be forgetting this!

    2
  4. 5

    Just use a table, idiot.

    -17
  5. 7

    Genius technique thanks :-)

    0
  6. 8

    Kim Andre Ottesen

    August 9, 2013 11:42 pm

    Great and flexible technique I’ve used quite a lot, e.g. when combined with Flexslider to create a sleek centered gallery.

    0
  7. 9

    Very useful article! My favorite technique is how Magnific Popup centers content, as its kept responsive and scrollbar is triggered when height is bigger then window, there was an article on SM – http://coding.smashingmagazine.com/2013/05/02/truly-responsive-lightbox/

    0
  8. 10

    Mark Petherbridge

    August 10, 2013 12:03 am

    Thank you for this wonderful and concise solution to all my hacky code. I do believe that you are about to save me a lot of time, and for that kudos.

    0
  9. 11

    Woaah! This solves a lot of problems for me. I used to do all sorts of tricks to get it right, including negative margins, but this is just perfect! I don’t use flexbox yet because of browser compatibility and display: table introduces a whole lot of problems in Firefox and IE for images (you can’t use min- and max-).

    0
  10. 12

    This gives so much relief…thanks for sharing!

    0
  11. 13

    Great resource, thanks for sharing. Alignments are always a nightmare! :D

    0
  12. 14

    I wonder what would be the best technique right now, to place vertically and horizontally centered text on image thumbnails (on hover) in responsive layouts, since we normally only set width on those elements, to fit the grid.

    0
  13. 15

    It’s smashing!thank you

    0
  14. 16

    That’s what browsers use to center standalone images.. since the dawn of time. Never looked at their code? :)

    0
  15. 17

    The first version DOES work on Windows Phone, at least WP8+IE10. It may not work in WP7/7.5+IE9 but browser share of that is getting smaller by the minute and was not high to begin with. But nice work!

    1
    • 18

      Thanks for the info! I need to get a BrowserStack account so I can try Absolute Centering out in all of the mobile browsers :-)

      0
  16. 19

    Irina Petculescu

    August 10, 2013 3:14 am

    great roundup, thanx

    0
  17. 20

    But no height: auto for divs, which is where it would REALLY be interesting and helfpul. It’s a good technique, no doubt, but it rarely comes to help. I’ve been doing top: 50%; height: X; margin-top: X/2; for the most part, and it works.

    For height: auto, I’ve been doing jquery events to change the margin-top on render and on window resize, and it works, but it requires javascript, which sucks.

    0
    • 21

      If you need height: auto, read over the Variable Height section for some tips, or you can try one of the alternative methods, like Table-Cell that will get it done without needing Javascript!

      0
  18. 22

    Thank-you! Goodbye, negative margins!

    0
  19. 23

    This is neat, but isn’t going to replace the table-cell method for me. I’ve been using table cell for a long time and have the markup/CSS snippets in my toolbox, so the one caveat isn’t concerning enough to trade for cross browser performance. Maybe I’m just not adventurous enough…

    0
  20. 24

    Very useful for all designer/developer. Thanks for sharing it.

    0
  21. 25

    Very useful….
    Thanks for this…… :)

    0
  22. 26

    Great article! These type of layout things can be troublesome when you are first getting started with web development. I was reminded of this recently talking to a junior web designer who just started and was expressing his frustration at getting things lined up right. I made sure to share this with him. Thanks!

    0
  23. 27

    Interesting technique. Another technique that is as versatile and effective, but IMHO more idiomatic, is the one exemplified here: http://jsfiddle.net/uy64k/4/ . This technique is a variation of the vertical-align/line-height technique (which to me, is the idiomatic way to achieve vertical alignment) that takes advantage of inline-block to allow for generic content.

    The only drawback, so far as I can tell, is that it inhibits line-height and font-size inheritance.

    0
  24. 30

    Thierry Koblentz

    August 10, 2013 1:00 pm

    There is another way to do this:

    http://jsfiddle.net/thierrykoblentz/cXwZn/3/embedded/result/

    The big advantage of this solution is that it does not require to style the box with explicit dimensions (width or height).

    0
  25. 32

    Excellent post. I saw this on Codepen and I am glad that this is shared.

    0
  26. 33

    I’d love to see a little JavaScript test that checks the browser to see if it’s capable of this method. Maybe a Modernizr-style test that puts either .shaw or .no-shaw on the HTML element.

    0
  27. 36

    This is such an easy way I was looking for so long. Thanks for sharing!

    Regards.

    0
  28. 37

    Interesting, cool and simple.

    *But*: why does this work? Should this really happen according to the CSS specification or is that just emergent behaviour that happens to be the same across all (most) browsers?

    0
    • 38

      Thierry Koblentz

      August 11, 2013 9:04 am

      Check this: http://www.css-101.org/block-level-elements/index.php

      Three of the seven properties can be set to auto:
      —————————————————————————-

      * margin-left
      * width
      * margin-right

      For replaced elements, a value of auto on ‘width’ is replaced by the intrinsic width, so for them there can only be two auto values.

      If exactly one of margin-left, width, margin-right is auto, the UA will assign that property a value that will make the sum of the seven equal to the parent’s width.

      If none of the properties are auto, the value of ‘margin-right’ will be assigned ‘auto’.

      If more than one of the three is auto, and one of them is ‘width’, then the others (‘margin-left’ and/or ‘margin-right’) will be set to zero and ‘width’ will get the value needed to make the sum of the seven equal to the parent’s width.

      Otherwise, if both margin-left and margin-right are auto, they will be set to equal values. This will center the element inside its parent.

      If auto is set as the value for one of the seven properties in an element that is inline or floating, it will be treated as if it were set to zero.

      0
      • 39

        Sorry, I should have been more specific. I meant vertical centering, which is achieved through

          position: absolute;
          top: 0; left: 0; bottom: 0; right: 0;
        

        In conjunction with

          margin: auto;
        

        As I said, it’s interesting that this seems to work, but why?

        0
        • 40

          Fritz,
          Here is my understanding of how this works:

          [1.] In the normal content flow ( http://taligarsiel.com/Projects/howbrowserswork1.htm#Layout ), “margin: auto;” doesn’t work on the top and bottom due to margin collapsing ( https://developer.mozilla.org/en-US/docs/Web/CSS/margin_collapsing and http://www.w3.org/TR/CSS2/visudet.html#normal-block “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 ( https://developer.mozilla.org/en-US/docs/Web/CSS/position#Absolute_positioning “…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. ( https://developer.mozilla.org/en-US/docs/Web/CSS/position#Notes “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). The margin of the [absolutely positioned] element is then positioned inside these offsets.” )

          [4.] Giving the block a width or a height prevents the block from taking up all available space and forces the browser to calculate the “auto” margin based on the new bounding box.

          [5.] Since the block is absolutely positioned and therefore out of the normal flow, margin collapsing doesn’t apply and thus the block is centered vertically. ( https://developer.mozilla.org/en-US/docs/Web/CSS/position#Values “Absolutely positioned boxes can have margins, they do not collapse with any other margins.” and most importantly… http://www.w3.org/TR/CSS2/visudet.html#abs-replaced-height “4. If at this point both ‘margin-top’ and ‘margin-bottom’ are still ‘auto’, solve the equation under the extra constraint that the two margins must get equal values.” AKA: center the block vertically )

          Whew. As best I can tell, this method is actually the intended use for “margin: auto;” based on the spec and will 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;”.

          0
        • 41

          Thierry Koblentz

          August 14, 2013 8:11 am

          @Fritz For the exact same reason as it works vertically – as explained on http://css-101.org.

          The browser uses “auto” to distribute the available space. The “margin box” is horizontally/vertically stretched and the box itself has an explicit width and height, so whatever is around the “border box” is the margin edge (margins are the available space), if opposite margins are both set to auto, then that value is split between the 2 opposite margins. Nothing magic, it is just the spec…

          As a side note, this has nothing to do with margin collapsing.

          0
          • 42

            Thierry,

            Looks like you’re right; margin collapsing isn’t exactly at play here. I may have misinterpreting the spec ( http://www.w3.org/TR/CSS2/visudet.html#normal-block “If ‘margin-top’, or ‘margin-bottom’ are ‘auto’, their used value is 0.” ) as margin collapsing, but it looks like it’s simpler than that. Thanks!

            0
          • 43

            I am not sure I can follow. css-101 even states that

            “Boxes with explicit dimensions do not stretch nor shrink.”
            ( http://www.css-101.org/absolute-positioning/03.php )

            As far as I understood it, defining a width and height plus defining an absolute position and top/left/right/bottom:0 is ambiguous (and according to css-101, only width and height will be considered and top/left/right/bottom is ignored).

            0
  29. 44

    Great technique. It’s hard to believe something like this isn’t common knowledge already.

    0
  30. 46

    Ive been trying to find this out for ages! Thanks a lot Thierry…

    0
  31. 47

    Great article!
    You made my day. Great work, thanks!!! :)

    0
  32. 48

    Hi, that worked; thanks.

    0
  33. 49

    Here is a great technique to absolutely center an element of variable dimensions:

    http://iclanzan.com/centering-variable-height-elements-both-horizontally-and-vertically-in-css/

    0
  34. 53

    Also done it this way:

    rule {
       width: 40;
       height:40%;
       position:absolute;
       left:50%;
       top:50%;
       margin:-20% 0 0 -20%;
    }
    

    negative left positioning against 1/2 of the total width

    0
  35. 54

    A great wrapup of solutions for a problem that has plagued many a web designer. Great article!

    0
  36. 55

    display: inline-block and pseudo-element method is also worth attention
    Fast fiddle: http://jsfiddle.net/7j5Da/

    Gumby framework uses this method. It also works for elements with unknown height.

    0
  37. 57

    Diego de Oliveira

    August 12, 2013 9:10 am

    Dude, I can’t believe… I was just searching a way to do a horizontal centered block with fluid size, and came here to see the latest news… and found this article! Just in time! Thank you!

    0
  38. 58

    This is awesome. Thank you !!

    0
  39. 59

    I know this solution seems like magic to everyone, but it’s not a magic silver bullet, because (as noted), the major caveat is that you have to set the height on the content element. If you have to set the height, then this technique is really no better than a whole bunch of other hacks (some noted here) like the negative margins, because if you have a fixed height, calculating what half the height is isn’t so bad.

    But it’s all those cases out there where you need vertical centering of a flexible height content box that we all really struggle with. When you are in that scenario, the translate(-50%,-50%) hack is more robust because it automatically calculates “half the height” for you regardless of how tall your content stretches.

    BUT, and this is the most important point I’d like to make, every single thing presented here, and in every other article like it over the years, is all about hacks to get CSS to approximate centering positioning.

    No, flexbox and tables are not the answer, they are bringing a sledgehammer to insert a pushpin. They are for layout structure, not precise positioning tasks. I explain why here: http://blog.getify.com/tables-flex-not-the-centering-youre-looking-for/

    What we finally need is a real solution that’s JUST for positioning. I tried to write up a bunch of these concerns in this post:

    http://html5hub.com/centering-all-the-directions/

    Unfortunately, a lot of people missed the real point there, where I submitted a simple soft-proposal for a better standard way of doing centering-positioning.

    0
    • 60

      Nice suggestion. As a beginner to CSS, i’d been led to believe that there *couldn’t* be a solution to vertical alignment, not that there just WASN’T a solution as yet :)

      0
  40. 61

    i’ve made this using jquery, best solution for me. Getting divs width&height and then get the window width&height and when the document is ready or resized, elements are positioned via .css property

    0
  41. 62

    Incredible that such tricks are needed, like spaggety code for a commodore 64, times have not changed in 30 years.

    0
  42. 63

    This is a great technique. It’s nice to have all of my center align options here, in one place.

    By the way, the “table comparison” link, near the end of the article, is broken. Is there any way to get that working? I’d like to check out the comparison chart.

    Thanks!

    0
  43. 65

    Hi Stephen,

    While the technique is useful the label absolute-center is not. Nothing in your class is about centering – how about:

    .Absolute-Fit-to-First-Relative-Parent-or-Body {
      margin: auto;  position: absolute;  top: 0; left: 0; bottom: 0; right: 0;
    }

    More explaining – less branding :)

    0
    • 66

      Hah. You’re right that the class on just that snippet of code isn’t completely semantic. However, the class name does make more sense on the first example code.

      Do you have any other suggestions for a more generic class name for the bare code? .Absolute-Fit-to-First-Relative-Parent-or-Body just doesn’t have quite the same ring to it! :-)

      0
      • 67

        I know this is a year old now, but… isn’t that what absolute means? Absolute to the first positioned parent?

        0
        • 68

          Essentially. Absolute positions the box within its containing block. ( http://www.w3.org/TR/CSS2/visuren.html#propdef-position )

          Jakob’s (sarcastic) remark was that the class name “.absolute-center” isn’t semantic, in that these properties alone don’t center the element, but rather cause the box to fill the containing block. A more semantic class would be something like `.text-center { text-align: center; }`

          While `.absolute-center` may not be strictly semantic, the intention of adding the class is very clear, in my opinion. Depending on your usage of the class, you could add some default widths and heights to ensure that adding the class will make the element appear centered, but since this article was about the technique, I made the class itself as universal as possible with the fewest necessary styles included.

          0
  44. 69

    Thank you so much for this awesome technique really that would be really helpful for me… Thank once again.. Cheers :)

    0
  45. 70

    Horizontal and vertical centering is a NP-complete problem!

    0
  46. 71

    Bookmarked! Thanks for this nice tool.

    0
  47. 72

    nice :)

    0
  48. 73

    I just wanted to report a Problem/BUG that’s related to Firefox/Chrome and the “Within Container” method here.
    If you want to get the “top” value in Javascript from the inner DIV, Firefox will display a calculated value while Chrome will return top: 0.

    Firebug also displays a different value than the webkit dev tool.

    This is an important fact that will break Javascript Animations and the likes.

    Here’s a fiddle:
    http://jsfiddle.net/kDAqE/4/

    EDIT:

    Example: If the top offset is 50px it will be like this:

    Firefox: top: 50px, margin-top: 0
    Chrome: top: 0px, margin-top: 50px

    0
    • 74

      Interesting bug. Chrome is returning the correct value (0) for .css("top"), since that is the declared value for top. Firefox however returns the top value plus the calculated margin.

      To get a consistent number cross-browser, use $('.inner').offset().top instead of position().top or trying to fetch the CSS top value. offset().top is the better method of detecting the distance from its offset parent, not just whatever the declared top value is. I also tested this with the inline-block method and table method, and offset().top returned the correct results in Firefox and Chrome.

      That said, you may run into some issues with built in animations or other plugins code if they use position().top or the declared top value, but you should be able to adapt them to use offset().top instead.

      0
      • 75

        Ahh yes the offset().top – thanks for that.
        I still think it should be pointed out in the article that FF will add the offset-value to the margin-top property. Other browsers i’ve tested (IE8 IE9 IE10 Chrome) will use the top property.

        0
  49. 76

    I like this. Awsome !!

    BUT , is there any method to implement the same in IE7 too. using css or jquery or both?

    0
  50. 78

    Oh Stephen! What a nice trick!! You should have discovered it years ago :P
    There is a little thing I can’t understand, when the container is smallest than the content, the horizontal centering is not working. Can you imagine a fix for that? Cheers.

    http://jsfiddle.net/marquex/ru2Mc/

    0
  51. 79

    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
  52. 82

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

    0
  53. 83

    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
    • 84

      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!

      0
  54. 85

    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 :)

    0
    • 86

      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
      • 87

        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
      • 88

        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
  55. 89

    Excellent tricks! Thank you.

    0
  56. 90

    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
    • 91

      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
  57. 94

    Clap, clap, clap!

    Good article!

    0
  58. 95

    Great post thanks mate.

    0
  59. 96

    Nice post. Covers everything.

    0
  60. 97

    This might be the best css solution of all time.

    0
  61. 98

    oldest and easyest way:

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

    0
    • 99

      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
  62. 100

    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!

    0
  63. 101

    Without declared height, only width/max-width.

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

    0
    • 102

      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
  64. 103

    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
  65. 104

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

    0
  66. 105

    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
    • 106

      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
  67. 107

    excellent
    thanks!

    0
  68. 108

    Thanks for this very well written, insightful and helpful.

    0
  69. 109

    thanks a lot for that

    0
  70. 110

    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
  71. 111

    Just what I needed! Thank you so much!

    0
  72. 112

    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
  73. 113

    Thanks man, saved my life :)

    1
  74. 114

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

    bradny

    -1
  75. 115

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

    Thank you!

    0
  76. 116

    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
    • 117

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

      0
  77. 118

    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

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