Getting Vertical With CSS

On Monday I discussed over at CSSquirrel my annoyance with vertically centering text with CSS. Any of you that have tackled this task have likely realized the chore that it is. For those of you who aren’t aware, it’s not as easy as it seems. Today, I’ll help show you how we can make it happen, despite CSS’s shortcomings.

Despite the fact that CSS has been around for at least fifteen years, and text has been in browsers since the very beginning, it turns out that unlike horizontally centering text (which requires only text-align: center) that there is no single, simple style that you’d use to center text vertically under all circumstances in all browsers.

I’m not sure why exactly this is the case. You’d think that the brilliant people behind CSS3′s Marquee module might have paused from their amazing brainstorming long enough to consider that there are plenty of cases where someone may want their text beautifully suspended in the exact middle of any number of elements, like roasted meat in a delicious sandwich.

Despite the fact that there’s no clean, multipurpose solution, there are ways to center text vertically. However, it’s case dependent.

Multiple Lines or Just One?

If you’re trying to center a single line of text, like a headline, the easiest, quickest, and most markup-light way to go is to give the text element a line-height that is equal to the height of the parent element (removing any padding or margin on the text-element as needed to keep it from being offset by that amount.) It’s quick, simple, and better yet doesn’t require any strange extra markup and works in all browsers.

Unfortunately, this doesn’t work where multiple lines of text are involved, as the result would be each line getting that height, promptly pushing any lines of text past the first below the bottom-edge of the parent element you’re trying to contain it inside.

One problem with text is that often, when multiple lines are involved, we’re not going to be in a position to say exactly how tall the text is. The amount of lines, the height of the text, all this could vary depending on font support on the end-users system and in many cases the text changes depending on what’s being entered by your client.

So how do we keep it centered?

There is a property called vertical-align, that has a value of middle, that would seem to do the trick. But try as you might, for the most part “vertical-align: middle” does jack except under two very specific circumstances: aligning inline blocks within blocks, and aligning table cells within rows.

Considering the name itself, you’d think it’d be more multi-purpose, gladly providing its service to all elements of all types. Sadly, no.

Despite these limitations, which annoy me beyond all belief, there is in fact a way to get this style to help us. You’re not going to like it, though.

If we take the text’s parent element, and give it the style display: table-cell and then vertical-align: middle. At that point the text within will be, no matter how many lines it contains, vertically centered.

Hooray!

Sort of.

Beyond the fact that this trick requires us to mimic a table-cell, which makes me sick, it has some limitations. First, IE7 and earlier won’t support it. I know that isn’t exactly heartbreaking for most of us web development people, but it’s a consideration if your client’s site has a notable demographic with those browsers.

Secondly, it makes the element in question behave like a table-cell, with all that entails. You’ll find some styles you’d want to use won’t work properly. In these circumstances, I suggest you wrap the text in an element that has the height/width of the parent as well as the table-cell/vertical-align properties attached to it rather than the parent.

No, I don’t want extra markup for something like this. But if a design needs it, it’s the cleanest method that currently works for it.

I’ve made a small demo page to show the technique for you, which you can visit here.

So, the end judgement? Vertically centering text is a pain. For now. But it can be done if you need it. And if we do it enough, maybe someone will get the idea that this is more important than Marquee styles.