Line heights in CSS work better with ratios

Say you’ve got this CSS and you need to set a nice, compact line height:

Code language
css
h1 {
    font-size: 40px;
}

You open up the designer’s static design and it says the line height should be 44px. Easy peasy, right?

Code language
css
h1 {
    font-size: 40px;
    line-height: 44px;
}

Technically, yeh: easy peasy. Let’s take a look at how that looks.

See the Pen by Andy Bell (@piccalilli) on CodePen.

Now let’s say the font size needs to be changed to 80px instead. How does that look now?

See the Pen by Andy Bell (@piccalilli) on CodePen.

Pretty crappy, right?

“Just change the line height again”, I hear from the distance. Yeh, but what if the line height wasn’t set in the same rule as the font size? You’re gonna get disconnect where you really don’t need to.

Step up, ratio-based line height. permalink

I’d say three good ways to do this would be:

  1. Unitless line height, like this: line-height: 1.1
  2. Em-based line height, like this: line-height: 1.1em
  3. Percentage-based line-height, like this: line-height: 110%

I’d also say it’s a good idea to use a relative unit to size the text while you’re there to give the browser—and more importantly—the user more control. Let’s pick a rem unit, which will be based off the user’s system font size, which if not set by the user, will be around 16px.

That switches our original CSS to this:

Code language
css
h1 {
    font-size: 2.5rem; /* 40 divided by 16 */
    line-height: 2.75rem; /* 44 divided by 16 */
}

Be wary of using em and % because the computed value is passed down to descendants. This article by Eric Meyer is a really good explainer. In short, I always recommend unitless if you want predictability


If we change the line-height to my preferred approach: unitless, the CSS now looks like this:

Code language
css
h1 {
    font-size: 2.5rem;
    line-height: 1.1;
}

Now, if the font-size was to change to something like 5rem (or 80px in the old way), that line height would change automatically with it and always be in proportion with the text.

Check out this demo and play with the font-size slider. You can also turn ratio-based line-height off to really see the improvement.

See the Pen by Andy Bell (@piccalilli) on CodePen.

Why though? permalink

Good question!

Setting very specific values may feel like you’re in more control, but you’re actually rescinding control by introducing fragility in the form of overly-specific CSS. The web is flexible and not at-all specific and we have no idea what the setup for our users is so the best approach is to make things as flexible as possible so your website works great for everyone.

This is especially the case when newer techniques such as fluid typography are considered. If the font size is determined like this…

Code language
css
h1 {
    font-size: clamp(2.5rem, 10vw, 5rem);
    line-height: 1.1;
}

…it won’t matter what the browser computes the font size as because that ratio-based line height will always be proportionate.

Handy, right?