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 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 article.
Further Reading on SmashingMag:
- The Definitive Guide to Using Negative Margins
- Flexbox Is As Easy As Pie – Designing CSS Layouts
- The Mystery Of The CSS Float Property
There, Simon linked to this jsFiddle that blew every other method out of the water (the same method was also mentioned by Priit in the comments). Researching further, I had to use very specific keywords to find some other sources 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 CodePen, Smashing Magazine, or message @shshaw on Twitter if you have any additional features or suggestions.
Find additional demos, a comparison table, and more on CodePen.
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 Height)
- Recommend setting
overflow: auto
to prevent content spillover (see Overflow) - 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:
- In the normal content flow,
margin: auto;
equals ‘0’ for the top and bottom. W3.org:If ‘margin-top’, or ‘margin-bottom’ are ‘auto’, their used value is 0.
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.org:…an element that is positioned absolutely is taken out of the flow and thus takes up no space
- 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 orposition: relative;
container. Developer.mozilla.org: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).
- Giving the block a
width
or aheight
prevents the block from taking up all available space and forces the browser to calculatemargin: auto
based on the new bounding box. Developer.mozilla.org:The margin of the [absolutely positioned] element is then positioned inside these offsets.
- Since the block is absolutely positioned and therefore out of the normal flow, the browser gives equal values to
margin-top
andmargin-bottom
centering the element in the bounds set earlier. W3.org: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
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;
.
The rest of the demos will assume these styles are already included and will provide add-on classes to implement various features. You can also stick your content block to the right or left while keeping it vertically centered, using 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;
}
position: relative
container to align the block within the container!
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;
}
position: fixed
and give it a high z-index, like the modal on this page.
position: relative
container.Offsets
.Absolute-Center.is-Right {
left: auto; right: 20px;
text-align: right;
}
.Absolute-Center.is-Left {
right: auto; left: 20px;
text-align: left;
}
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
.
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;
}
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;
}
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;
}
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
andtransition
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;
}
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 technique. 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.
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;
}
max-height
. This makes it ideal for responsive scenarios, just make sure you set an appropriate overflow.
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 Kalley at ELL Creative 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 technique if the Modernizr test doesn’t meet your needs.- Not compatible with the Resizing 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 Margins, Transforms, Table-Cell, Inline-Block, and now Flexbox. 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 */
}
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 usebox-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%);
}
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
Read more about Transform Centering in Chris Coyier’s article “Centering Percentage Width/Height Elements” on CSS-Tricks.
Absolute Center, Translate(-50%,-50%).
This box is absolutely centered vertically within its container usingtranslate(-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;
}
Advantages:
- Variable height content
- Content overflows by stretching the parent element
- Works well cross-browser
Caveats:
- Requires extra markup
Read more about Table-Cell Centering in Roger Johansson’s article “Flexible height vertical centering with CSS, beyond IE7″ on 456bereastreet.
Absolute Center, Table/Table-Cell.
This box is absolutely centered vertically within itsdisplay: 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+ */
}
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 Unknown. 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-Cell 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 CSS 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.
Read more about Transform Centering in Chris Coyier’s article “Centering In The Unknown” on CSS-Tricks.
Absolute Center, Inline-Block.
This box is absolutely centered vertically usingdisplay: 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;
}
Advantages:
- Content can be any width or height, even overflows gracefully
- Can be used for more advanced layout techniques.
Caveats:
- No IE8-9 support
- Requires a container or styles on the body
- Requires many vendor prefixes with different syntaxes to work on modern browsers
- Possible performance issues
Read more about Flexbox Centering in David Storey’s article “Designing CSS Layouts With Flexbox Is As Easy As Pie” 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 table 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-Cell, Inline-Block techniques. If you’re on the bleeding edge, give Flexbox a try and reap the benefits of its advanced layout techniques.