Friday, April 20, 2007

Setting Type on the Web to a Baseline Grid

We web designers get excited about the littlest things. Our friends in the print world must get a kick out of watching us talk about finally being able to achieve layouts on the web that they’ve taken for granted for years. Let’s face it: it’s easier these days to embed a video on the web than it is to set type consistently or align elements to a universal grid.

But we’re scrappy folks, web designers. We don’t give up easy. In the long slow battle with browser support and platform inconsistencies, we’ve been able to bring more and more sophisticated print techniques onto the web—sometimes kicking and screaming.

We have the technology

Over the last year or so, there’s been a lot of talk about grid systems and using column grids for website layouts. Mark gave us a
lesson plan, Khoi gave us a case study and Cameron gave us a toolkit. The message is clear: we have the browser support, the know-how, and the tools we need to create consistent multi-column grid layouts on the web.
We can apply the same principles of proportion and balance to the type within those columns by borrowing another technique from our print brethren: the baseline grid.
The main principle of the baseline grid is that the bottom of every line of text (the baseline) falls on a vertical grid set in even increments all the way down the page. Imagine those old
Big Chief ruled writing pads they gave you in grade school to practice penmanship and you’ve got the basic idea. The magical end result is that all the text on your page lines up across all the columns, creating a harmonious vertical rhythm.
In print, it’s not that hard. Just enable the baseline grid in Quark or InDesign and set the increment based on the line-height you want. On the web of course, it’s another story. It’s hard enough to align things vertically with CSS because it’s tough to predict where every element will fall, and it only gets worse when we’re dealing with type, which is hard enough to size consistently on its own. But with a little math and a slightly obsessive attention to detail, we can make it work.

Firing up the grid

Note: I’ve used pixel units for sizing text in the examples for this article. Recognizing that this may be a surprising recommendation for an article in this publication, I’ve addressed some of my reasons for doing so—as well as some alternate techniques that use relative units—further down.

The first thing we have to do is set a line-height for our grid. I’ve chosen a pretty standard base font size of 12 pixels, and set the line-height at 18 pixels, which gives us a nice open leading of about 150%. It’s important to think about your line-heights up front. You want a ratio of font size to line-height that’s a good balance for readability and that’s easily divisible into smaller units (more on this later).

I’ve also borrowed a trick from
Khoi and created a tiling background image that I can use on the page while I’m working to make sure everything lines up where I want it to. You can see the end result with the grid turned on in this example.

You’ll notice in the previous example that the text doesn’t fall directly on the grid lines. Because of the way CSS renders line-height (by adding space above and below the letters) it’s a lot easier to line the text up within the grid lines rather than directly on them. It’s possible to adjust your background image to take this into account, or tweak the padding on certain elements so the text starts in a different place, but there’s no point making this more complicated than it needs to be.

Paragraphs and headers


I’ll start by resetting the margin and padding on everything to zero so we don’t have to worry about default browser styles. In practice, you’ll probably want to use something a little more precise, but for the purposes of this example, a good old star selector will do just fine.

* {
margin: 0;
padding: 0;
}

We want space between paragraphs, but the default top and bottom margins of 1em (which works out in this case to 12 pixels) won’t work with our 18 pixel grid, so we’ll set the bottom margin on paragraphs to 18 pixels.

p {
margin-bottom: 18px;
}

As we set the font size for headers, we also need to set appropriate line-heights in multiples of 18, as well as adding the 18 pixel bottom margin.

h1 {
font-size: 24px;
line-height: 36px;
margin-bottom: 18px;
}

h2 {
font-size: 18px;
line-height: 18px;
margin-bottom: 18px;
}

h3 {
font-size: 12px;
line-height: 18px;
}

The pattern is pretty simple. Any time you add vertical space with a margin or padding, you need to add it in units of 18 pixels to maintain the baseline grid. You don’t always have to add it in one place, but you need to add it in pairs that add up to 18 pixels. For instance, you could set a top margin of 12 pixels and a bottom margin of 6 pixels.


Lists

Lists are a little bit tougher. We’re used to adding a little padding between each list item and before or after a nested list. Depending on your grid size, you may have to choose between adding a lot of extra space (adding a full grid line) or adding none at all and letting list items fall on the regular grid lines.
Since the 18-pixel line-height we started with is pretty generous, the “none at all” option works pretty well here. I’ll just add the bottom margin of 18 pixels.

ul, ol {
margin-bottom: 18px;
}

As for nested lists, it’s possible to add half of your line-height (in this case, 9 pixels) of margin above and below nested lists. Adding half a line to the top and another half to the bottom means the contents of the list will be “off the grid,” but the grid will get back on track once the list ends. It’s a compromise, but sometimes worth it for designs in which you need to accommodate especially long or complicated nested lists.


Floats and sidebars

Here’s where a little discipline comes in. Images and other elements floated within your text need to be sized vertically in multiples of your grid increment: in this case, multiples of 18. If they’re sized correctly, you can add margins around them that add up vertically to a multiple of 18, and the text will always break in the right place, directly under your image.


.left {
float: left;
margin: 0 18px 18px 0;
}
.right {
float: right;
margin: 0 0 18px 18px;
}

Other floated elements like callout boxes are a little bit more complicated, since it’s harder to predict their height based on the content inside. As long as all text and images inside the float follow the 18-pixel rules, and you always add vertical padding and margins in groups that add up to 18, everything should line up no matter what you put inside.

.callout {
border: 1px solid #ddd;
padding: 8px 10px;
margin-bottom: 18px;
}

Notice that I added 8 pixels of padding to the top and bottom of the floated element, since the border width already accounted for 2 pixels of added height (8 + 8 + 1 + 1 = 18).
I’m also going to suck out the bottom margin on the last element in the callout so we don’t end up with too much extra space inside. This isn’t a critical layout feature (the grid is still intact without it), so I’ll go ahead and use the :last-child pseudo class since it doesn’t require me to add any extra markup. IE6 won’t get it, but it won’t break the layout.

.callout :last-child {
margin-bottom: 0;
}

The important thing to remember with callouts and sidebars is to keep the line-height the same even if you make the text smaller. You might be tempted to tighten it up, but even for 11- or 10-pixel font sizes, 18 pixels is still a very readable line-height.


All your baseline are belong to us

You can see it all put together in this example. If you don’t believe me, put your rulers away and check it out with the background grid visible.

You can start to see why baseline grids aren’t used very often on the web. It’s pretty tough to keep up with it—especially as your layouts get more complicated—and we’ve only touched the surface of some of the relatively manageable challenges. Just as in print, baseline grids are not always the right choice for every layout, and sometimes you need to make exceptions or exclude certain elements from the grid to make a layout work.

But it’s definitely possible, and something that’s worth experimenting with, especially in combination with a horizontal or column grid. A nice balanced baseline grid—even just within the main content area—can add polish and readability as we move typesetting on the web to the next generation with CSS3 and beyond.


Don’t fear the pixel

One final note on font sizing: I’m using pixels instead of ems in this example for one reason: it makes everything simpler. With pixels, I can set one base line-height for the entire document and I don’t have to recalculate it whenever I use a smaller font size. When designing a practical system like this, it’s important that it’s relatively easy (for yourself and others) to use and maintain.

You can use relative sizes, but it quickly becomes a lot more difficult to maintain as the math becomes more complicated. It’s easy to get 12 out of 18 (just set the line-height to 1.5em), but when you want to adjust the text size but keep the same line-height, the fractions start to get messy, and predicting how browsers are going to round your values makes it hard to be exact. It’s certainly possible however, and if you’re interested in trying something similar with relative text sizes, I’d recommend checking out Richard Rutter’s excellent
24 ways article, Compose to a Vertical Rhythm.

In the end, it’s a tradeoff. Most browsers will scale pixel-based line-heights proportionally along with the text. Of course, the margins don’t scale, and neither do the images. But is it worth making the system more complicated just to make the margins scale if the images don’t? It depends on the situation. In the end, it’s up to you.

At some point as designers we have to strike a balance between creating pixel-perfect layouts and infinitely flexible ones. When you get down to it, resizable text is primarily an accessibility feature, not a design feature. Ideally it’s something that should be provided by the browser, no matter how the page is built, and in modern browsers it is. As long as all your content is readable and accessible at all sizes, it’s not necessarily true that the design must maintain integrity as you scale.

No comments: