Centering an Inline-Block With Vertical-Align: Middle (CSS)

The CSS properties display: inline-block and vertical-align: middle provide a flexible and maintainable way to center any content inside a <div>. The height of the <div> does not even need to be known and can by dynamically determined by its content.

Let’s jump right in and start with

A Quick Example

Yay, I'm centered in the blue area!
Click to change content height

The minimal markup and CSS:

<div class="container">
  <div class="center-area"><!--
 --><div class="centered">
      Yay, I'm centered in the blue area!
    </div>
  </div>
  <div class="content">
    <!-- Some content defining the
         height of the container -->
  </div>
</div>

<style type="text/css">
  .container {
    min-height: 8em;
    position: relative; /* so center-area can
                           be positioned absolute */
  }
  .center-area {
    /* let it fill the whole container */
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
  }
  .center-area:before {
    content: '';
    display: inline-block;
    vertical-align: middle;
    height: 100%;
  }
  .centered {
    display: inline-block;
    vertical-align: middle;
  }
</style>

This approach has a few advantages:

  • You don’t need to know the dimensions of the elements to be centered.
  • The CSS doesn’t need to know the the size of the .center-area.
  • The height of the .container can be defined by its content which can change dynamically.
  • It’s markup is relatively clean. Only one helper element (the .center-area) is required.
  • It is able to vertically align more than one element next to each other.
  • It is supported across all browsers.

But there is still a caveat. You have to take care of the white-space between inline-elements in your mark-up. The markup looks like:

<div class="center-area">
  <div class="centered"></div>
</div>

If we included the pseudo-element, it would look like:

<div class="center-area">::before
  <div class="centered"></div>
</div>

So, there is white-space between the ::before and the <div.centered>: a line-break and some spaces. It all collapses to one space according to the rules html is processed by. This single space is nudging our centered element a bit to the right and might break the layout.

The space’s size also differs for different fonts. For example, it is .625em for Courier and .25em for Helvetica. To keep that out of the equation, the white-space must be removed. There are two options:

  • Put both opening tags into one line:

    <div class="center-area"><div class="centered">
    </div></div>
  • Keep the indentation and add a comment to filter out the line-break and spaces.

    <div class="center-area"><!--
     --><div class="centered"></div>
    </div>

Changing the indentation of the mark-up or adding comments at the right places can be frustrating to maintain. But once you know it, it is quickly fixed.

If you despair of vertical-align from time to time, I recommend having a look at the 3 reasons why vertical-align is not working.