“The best way to vertically align something in CSS is to close your laptop and head out to the bar.” (Or something to that effect, read in passing on Twitter.) Even in these days of CSS3 where styling has advanced so much, it’s still a pain to vertically center anything.

Until there’s a better way, here’s something that works:


<!-- containing element to implement centering trick on -->
<div class="wrapper"><!-- element to center -->
  <div class="container">
    <h1>Hello World</h1>
    Hi, I am page content.


.wrapper {
  /* set the height of the element which contains what you want to center */
  height: 100%;
  /* these styles are optional, to set width horizontally center the page */
  max-width: 500px;
  margin: 0 auto;
.wrapper:before, .container {
  /* these are the important styles for the centered element: */
  display: inline-block;
  vertical-align: middle;
.wrapper:before {
  /* this is the important part */
  content: '';
  display: inline-block;
  width: 0;
  height: 100%;
  vertical-align: middle;
  /* this just takes care of whitespace added by having display:inline-block (there are other methods) */
  margin-left: -0.25em;

The major benefit of this method over others is that it doesn’t use tables or display:table-cell (which has its own quirks) and the height of the element to be centered doesn’t need to be known. The main drawback is that the containing element needs a set height. You also have to watch for the white-space caused by using display:inline-block and have an extra containing element (as in this example) or text-align properties to horizontally center the box as well. I first came across this idea on a coderwall pro-tip and thought “hey, why didn’t I think of that?” But I don’t like the extra markup, and I see others didn’t either—they’ve since commented with versions using pseudo-elements like this one.

  • Nice tip! Thanks!

  • Allison Beh

    Smart technique! Thanks for sharing. 🙂

  • Hi, I realized on Firefox your trick may not appear accordingly, and I found that I have to slightly reduce the width of the centered element for correct display on Firefox. For instance, in the above example, the width of the .container is 90%, together with left and right paddings (5% each) the total width is therefore 100%. On Firefox, this will cause the centered element to be placed at the second row. Reducing the width of .container from 90% to 89% will solve the problem.

    Thought this may help to eliminate some confusion. Thanks again. 🙂

    • Hi Allison,

      Good catch on the Firefox issue, but it doesn’t require changing the width of the centered element to fix it – this is an example of the white-space problem. So, instead of having the correction on the .wrapper:before pseudo-element, move it to the centered element as a negative left margin instead. I’ve updated the example.

      The main reason I don’t really like this method, although it usually works quite well, is that it relies on a ‘magic number’ of sorts to account for the space. Making that number relative (em) seems a bit better. Most space sizes are 0.25 – 0.3em.

      • Markus

        Actually you don’t need to use a ‘magic-number’ (which might not work in every browser). You are probably better off using HTML comments to get rid of the whitepace. Here’s a simple example: http://codepen.io/anon/pen/scCFe

    • Actually, the negative margin should work in either location.

  • Rogier

    Any idea how to use a static footer with this solution? Like peterned.home.xs4all.nl/examples/csslayout1.html? Help much appreciated!



    • Unfortunately, this solution doesn’t work with min-height. It needs a fixed height on the containing element.

  • Bruno Caxito

    Thank you very much. It has much more compatibility than the current solution from W3schools.

  • Jay2k1

    I have a three column page layout with the left and right column divs having a fixed width and the middle div (which is my wrapper div) being fluid. For this reason, I have margin: 0 200px on the wrapper div (the left and right divs have a width of 200px each). This combined with your method causes the wrapper to have a slightly bigger height than the viewport. This can be worked around by decreasing the height of #wrapper:before to 90% (in my case), but then the container is no longer perfectly centered. Any idea?

    • Ben Ceglowski

      Hi Jay2k1,

      Would you perchance be able to put an example of your code in a CodePen? (http://codepen.io) – we can help root out the issue and get back to you.

      Issues can arise when this technique is used alongside an explicitly set white-space, padding or border, as well as when an inline-block displaying :after pseudo-element is also in use.

  • Seldom

    All of that ‘<‘ (AND ELL TEE) is painful to try and read. It’s appearing instead of the actual angle-brackets it should be showing. Kindly requesting you fix it, at least assuming there are other Chrome users here looking.

    • Ah shoot! Sorry about that, I fixed it up for you!

  • Samir

    Awesome trick. works great!!

  • Pingback: How to Use Inline-Block • Phuse()

Discover and implement your big idea with our product team

Get in Touch