Posts from Wednesday, February 8th, 2006

Unitless line-heights

Published 12 years, 1 month ago

I’d like to share something that will be old news to readers of CSS: The Definitive Guide and all of my other books, but nonetheless needs to be said out loud, in public, for everyone to hear.

The property line-height can accept unitless number values.  You can also give line-height united values, though generally you shouldn’t.  But unitless numbers are just fine for this property.

So what’s the difference?  When you define a united value, like 1em, you’re setting things up to pass along the computed result to any descendants.  For example, suppose the following CSS is applied to a document containing the following markup fragment:

ul {font-size: 15px; line-height: 1em;}
li {font-size: 10px;}
small {font-size: 80%;}

  <li>I'm a list item with <small>small text</small>.</li>

The ul element has its line-height computed to be 15px because for line-height, em-based values are calculated using the computed font-size of the element itself.  I declared the font-size directly, so we know its computed size in pixels.

(Yes, yes, I know, pixel-sized text is evil and wrong, but it makes explaining how all this works a lot simpler.)

So that computed value of 15px is what’s passed on to the descendent elements.  The li and small elements will inherit a line-height value of 15px.  End of story.  They don’t change it based on their own font sizes; in fact, they don’t change it at all.  They just take that 15px and use it, exactly the same as if I’d said:

ul {font-size: 15px; line-height: 1em;}
li {font-size: 10px; line-height: 15px;}
small {font-size: 80%; line-height: 15px;}

Okay, now suppose I take the em off that line-height value, so that the styles now read:

ul {font-size: 15px; line-height: 1;}
li {font-size: 10px;}
small {font-size: 80%;}

Now what’s passed on is that raw number, which is used by descendent elements as a scaling factor—a multiplier, if you will–and not the computed result.

Thus every element that inherits that value of 1 will take that value and multiply it with their computed font-sizes.  The list item, with its declared font-size: 10px, will have a computed line-height of 10px.  Then it will pass that 1 on to the small element, which will multiply it with its computed font-size.  That’s 8 pixels; therefore, its line-height will also be 8 pixels.

The end result is exactly the same as if I’d written:

ul {font-size: 15px; line-height: 1;}
li {font-size: 10px; line-height: 10px;}
small {font-size: 80%; line-height: 8px;}

That’s a pretty major difference.  This is why it’s always strongly recommended that you use unitless numbers if you’re going to set a line-height on something like the html or body elements, or indeed on any element that is going to have descendant elements.

The fact that the CSS validator has a bug that causes it to generate parse errors on unitless number values for line-height (see report #2307) rather confuses things; we get an occasional jeering e-mail over at A List Apart as a result, since running CSS validation on the site gets an error due to my use of line-height: 1;.  Jeffrey points the correspondents to that bug report, and usually we never hear anything back.

And if anyone reading this feels motivated to fix the validator, please do.  As it says in the bug report, all they really need is a patch for review.  I might do it myself when I have some free time.  That’ll be in, oh, 2009 or so.

Again: the property line-height can accept unitless number values, and they’re a better choice than united values in 99 out of 100 cases anyway.  Okay?  Thank you.

[Addendum 26 Aug 06: Roger Johansson points out a bug in older Gecko browsers relating to unitless line-heights.]

  • Published
  • Categorized under CSS
  • 108 responses so far