Feb 12 2009

Bottom and Middle Vertically Aligned Titles with CSS

One thing I’ve really missed since migrating to standards-based (i.e. table-less) web design is the ability to vertically align elements, such as bottom-aligning text inside a block space, so the text will stay bottom-aligned when the browser’s text size is changed. With tables, it’s easy, just add valign="bottom" and you’re done. But with CSS and semantic HTML, it’s unfortunately not that easy yet.

I have taken inspiration from reading Eric Meyer’s writings about the One True Layout, especially about performing math with CSS properties.Then I thought, “why could we not use the concept of ’CSS math’ to do other things?” So I did!

The concept is simple: use the padding and margin of two nested elements to add and subtract different units (make sure both are set to display: block;). The key here is that you have to use the padding as the number to add and use the margin as the number to subtract. If you reverse them, then your text will disappear behind the top of an element’s bounding box.

The only caveat is that this technique is dependent on the number of lines of text remaining the same (except at extremely large text sizes, at which legibility is really the only concern). Thus, it works best for situations where your titles are determined ahead of time or are guaranteed to be short. It’s not really great in situations like blog entry titles where you typically don’t know how long titles will be on future entries.

Bottom Aligned Titles

For bottom aligned titles, the first step is measuring the distance between the top of the element and where you want the baseline to fall. By measuring to the baseline of the text, we ensure that when the browser’s text size is changed, the text resizes upwards instead of downwards. In figure 1 below you will see that our sample distance is 100 pixels. Set this distance as the top padding of your block element (padding-top: 100px).

illustration of element with a top padding of 100 pixels
figure 1

Now we get to use the magic of ems for the second part. Those of you who haven’t explored the unit “em” need to do some more reading, because it’s an awesome thing. Basically, one “em” is equivalent to the current text size, and it changes whenever the text size changes. The benefit here is that we can move up our titles using “lines of text” as the unit. If your line-height is 1 em, then 1 em is your “line of text” equivalent. Thus: 1 em would be one line of text, 2 ems would be two lines of text, etc. So in the case of a single-line title, we give the inner element a top margin of -1 em (again, make sure it’s set to display: block;), as you can see in figure 2 below.

illustration of a nested element with a top margin of -1 em
figure 2

Voila! Your text is magically bottom-aligned!

Middle Aligned Titles

If you want your titles to be middle-aligned, it’s the same process, just altered slightly. First, instead of measuring the top padding to the text baseline, measure it to the middle alignment point. Then, when applying the negative top margin to the inner element, use half of the line height instead of the whole value.

It’s that easy!