“Vertical-align isn’t working!” cried the web developer.

The vertical-align property is one of those features of CSS that sounds pretty self-explanatory, but can cause problems for CSS beginners. I think even many CSS veterans have had problems figuring this one out at times.

In this post, I’ll try to cover it in an understandable manner.

What it Does Not Do

The common misconception about vertical-align is that, when it’s applied to an element, it will make all the elements inside that element change their vertical position. For example, when using vertical-align: top on an element, it’s assumed that the contents of that element get pushed up to the top of the element.

This reminds me of something we used to do back in the days of table-based layouts:

<td valign="top"> Whatever... </td>

In the case of this table cell example, the “valign” property (now obsolete in HTML5) would cause the elements inside of it to get pushed to the top of the table cell. So naturally, when CSS developers start using vertical-align , they assume the same thing — that the contents of the elements become aligned in accordance with the property’s value.

But this is not how vertical-align works.

What it Actually Does

The vertical-align property can be broken down into three easy-to-understand steps:

It only applies to inline or inline-block elements It affects the alignment of the element itself, not its contents (except when applied to table cells) When it’s applied to a table cell, the alignment affects the cell contents, not the cell itself

In other words, the following code would have no effect:

div { vertical-align: middle; /* this won't do anything */ }

Why? Because a <div> is a block-level element, not inline. Of course, if you converted the <div> to an inline or inline-block element, then the vertical-align property would have an effect.

On the other hand, when used correctly (on an inline or inline-block element), the vertical-align property will cause the targeted element to align itself in relation to other inline elements.

How high up or down an element is aligned would depend on the size of the inline elements on the same line, or on the line-height set for that line.

Some Visuals

Here’s a visual demonstration along with explanatory text to help you grasp what’s happening when you vertically align an inline element:

And here’s a JS Bin that has some mixed inline elements with one of them aligned vertically to the top:

Keyword Values

The different keyword values that you can use with vertical-align are:

baseline (the default or “initial” value)

bottom

middle

sub

super

text-bottom

text-top

top

It’s likely you won’t use many of these, but it’s good to know the variety of choices you have. For example, in the demo page, because the value for vertical-align is set to “top” for the input element, it aligns with the highest element in the line (the big image).

But if you don’t want to align the element in relation to images or other block-like inline elements, then you can instead choose the values text-top or text-bottom , so the element will align in relation to the text on the line.

About the Value “middle”

Unfortunately, vertical-align: middle will not align the inline element to the middle of the largest element on the line (as you would expect). Instead, a value of middle will cause the element to be aligned with the middle of a hypothetical lower-case “x” (also called the “x-height”). So, it seems to me that this value should actually be called “text-middle” to correctly identify what it does.

See this demo where I’ve bumped up the font size so that the x-height is much larger. So generally speaking, a value of “middle” won’t be used very often.

Non-Keyword Values

Something you might not be aware of is that vertical-align accepts length and percentage values. So these would all be valid examples:

input { vertical-align: 100px; } span { vertical-align: 50%; } img { vertical-align: -300px; }

Although you can read an explanation in the spec describing what the keyword and length values do, I think it’s much more useful to just fiddle with the values yourself and compare different results.

Conclusion

If I can sum up how to use this traditionally misunderstood property in one sentence, I’d say: