It's 2015 and let's face it, it's easier to create a smooth transitioning mobile menu using only CSS than it is to vertically align an element in the centre of a page. Why can't it just be ‘vertical-align: middle’ and be done with it?

Reaching Your Vertical Limit with Centre Aligning

The issues here are that HTML layouts were not originally designed to specify vertical behaviour. Text naturally flows from left to right, and increased content forces an appropriate height based on the set width available. When HTML and CSS were first created, no one ever thought we would have to vertically align anything, but why is it, with it’s increased need, there hasn’t been an overall ‘fix’ that works in all browsers and on all devices without using an essay of code?

Vertical Alignment in CSS

Why isn’t there a universal standard which solves all of our coding headaches?

The Judgement

Horizontal centering is easy. if you have an inline element, you use text-align: centre on it’s parent. When you have a block element, we give it a width and set the left and right margins with a value of auto.

The style: ‘vertical-align:middle’ sits on the content element itself, and doesn’t describe its position in its parent, only its position with respect to other inline content around it. This pretty much means it’s only good for getting inline text and inline images to work nicely next to each other. What you can do, however, is use ‘vertical-align: middle’ in conjunction with other style elements based off your specific situation.

That being said, here’s a run down of all the variations of vertical alignment.

The One with the Line Height

If you only have a single line of text within a container, you can vertically align the text using the line-height property.

.container {
    line-height: 100px;
    padding: 0 30px;
    width: 300px;
    margin-left: auto;
    margin-right: auto;
}

The One with the Tables

Using the table CSS trick is great when ensuring it works on old browsers like IE8.

This method is done by setting the container element display to table, while the child element is to be displayed as table-cell then use the 'vertical-align' property to centre text vertically.

.container {
    display: table;
    height: 100px;
    margin-left: auto;
    margin-right: auto;
}
.content {
    display: table-cell;
    vertical-align: middle;
    padding: 0 30px;
}

The One with the Transformers

This has to be one of my favourites as it’s simple, clean, and comes with it’s own mixin for ease of use. It doesn’t require you to know the height of the element, and it works on more than one line of text.

.element {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}
/* Mixin */
@mixin vertical-align {
    position: relative;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}
.element p {
    @include vertical-align;
}

Notably, some blurriness may occur due to the placement of the element being on a ‘half pixel’, so a work around would be to set the parent element to preserve-3d.

.parent-element {
   -webkit-transform-style: preserve-3d;
   -moz-transform-style: preserve-3d;
   transform-style: preserve-3d;
}

The One with the Defined Height

If you need to know the height of the element you want to vertically align, using negative margins to centre your element.

By changing the height % of your content div and multiplying it by -.5 to get your margin-top value, it will ensure that it works on every browser

.container{
    position: relative;
    display: block;
    height: 100px;
    width: 100px;
    margin: 10px;
}
.content {
    position: absolute;
    top: 50%;
    height: 50%;
    width: 100px;
    margin-top: -25%;
    text-align: center;
}

The One with the Flex Box - the New Kid on the Block

Fairly new to the game (although it has technically been around since 2009!) is Flexbox. It’s a simple and powerful tool allowing for the distributing of space and aligning content in ways that web-apps and complex web pages often need. According to the W3C specification, it allows for the following:

  • can “flex” their sizes to respond to the available space
  • can be aligned with respect to their container or each other

There is a handy guide over at caniuse.com which shows which browsers flexbox can be used on

Flex box only needs 3 elements to allow the magic to happen:

.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}

If you make the flex-direction vertical (using column) then 'justify-content: center;' centres vertically. Then you can just use 'text-align: center;' to centre horizontally as well.

.parent {
    flex-direction: column;
}

The All Inclusive

This is a pure CSS2 solution for horizontally and vertically centring without known sizes of either container nor child.

The code is based on vertical-align: middle, in conjunction with line-height: 0, which parent has a fixed line-height.

html, body {
    height: 100%;
    width: 100%;
    padding: 0;
    margin: 0;
    overflow: hidden;
}
.container {
    position: relative;
    display: block;
    top: 50%;
    margin-top: -175px;
    height: 250px;
    text-align: center;
    line-height: 250px;
}
.content {
    line-height: 0;
    vertical-align: middle;
}

Conclusion

Although there is no simple run of the mill solution which fits every circumstance, there is a whole host of tricks which can accommodate most situations when trying to vertically align content.

One day, hopefully not in the distant future, developers will be able to use a simple 'align: all' to position an element dead centre on a page, and be done with the tedious research into which method will work best.

0
Ignite your brand, utilise user-generated content no matter where you or your audience are ›