Molten leading (or, fluid line-height)

Fri, 3 Feb 2012

This is not a demo. I’m only explaining a need as I see it. I don’t have the JS chops to make it real. Maybe you do?


Original post

When a responsive composition meets a viewport, there are different ways to fill space. What interests me most here is a fundamental triadic relationship in typesetting — that of a text’s font size, line height, and line length. Adjusting any one of these elements without also adjusting the others is a recipe for uncomfortable reading, which is one reason designers have such a difficult time with fluid web layout.

One way to fill space is to scale text while keeping its proportions intact. This preserves the size/leading/measure relationship, and can work really well for some experiences (see Mark Hurrell’s post on orientation and fluid grids). But an increase in font size can be jarring to readers; A larger font size affects reading distance comfort. If I were to rotate my iPad while reading, and the text scaled up, I can imagine needing to hold the device a few inches farther away as a result. This is not what designers want to have happen to text intended for reading.

In retrospect, this was a bad example. Some designers and readers may not want this to happen, but others epxect rotating a device to scale the type.

Another way to fill space is to use fluid widths. The problem in this case is that CSS line-height is tied to font-size, which is rooted in browser font sizing and environmental resolution, while line length is based on width, which is rooted in viewport dimensions. So a carefully balanced relationship among font size, line height, and line length easily breaks down. We end up with line lengths that feel too long, font sizes that seem too small, line spacing that feels too tight or loose.

What we need is a fluid way to set line height. Web designers should be able to define line height as a range, like we do with min- and max-width. I made a simple page to visualize how I’m thinking about this. Molten leading would maintain a specific font-size while adjusting line-height based on width. In other words, I would essentially like to tween a paragraph from this:

width: 15em;
line-height: 1.3;

To this:

width: 36em;
line-height: 1.4;

So that it would be possible to find line height dynamically at any given point in between:

width: 30em;
line-height: 1.371428571;

To find that line-height value, I used this formula: ((current width − min-width)/(max-width − min-width)) × (line-height − min-line-height) + min-line-height = line-height. With actual values, that’s: ((30em−15em)/(36em−15em)) × (1.4−1.3) + 1.3 = 1.371428571.

What I’m not sure about is how to get the min/max widths of an element that are needed for this formula. If CSS authors routinely defined elements’ min-width, max-width, line-height, and some kind of min-line-height, that’d of course be ideal for this:

p {
  max-width: 36rem;
  min-width: 15rem;
  line-height: 1.4;
  -js-min-line-height: 1.3;

But that’s not always practical. Often, the width limits of a given text block will be determined by percentage-based inheritance (66% of the parent element, which is 85% of its parent element…). It’d take some box model math to identify those narrow/wide limits. A script would have to figure out, for a given element, how wide/narrow can this grow?

If it’s possible to glean that information from existing CSS rules, then the only thing designers would need to define explicitly is a minimum line height. That value could be passed as a function argument, or maybe found in the CSS by looking for that -js-min-line-height rule in my example above.

This feels like a step toward more natural typographic behavior on the web. I’m just not sure where to go from here.

Also, for what it’s worth, Andy Clarke talked about this in 2010. His solution was to use media queries:

Type tip: As the width of the measure (line width) becomes wider, leading (line-height) should be increased to aid readability.

How can we solve this, and adjust the amount of leading as the width of a browser window changes? With CSS3 Media Queries.

What I’m talking about is augmenting CSS with range rules (effectively, min/max line-height) that don’t yet exist, but should for the sake of fluidity.