Blog Type Space Alt2

Opinionated Typography: Space

Written by Paul Woods.
Published on 12 October 2026.

My typo­graph­ic opin­ions remain unashamed. This time, I’m look­ing at space: the space that con­tent occu­pies and the space that sur­rounds it.

Contents

Line length

This is prob­a­bly less of a prob­lem on mobile, but larg­er screens present a choice. How long?

Indeed, blocks of text that stretch across the width of a big screen can be tricky to read. Even Wikipedia has realised this.

Accord­ing to UX Col­lec­tive, line lengths should be ​“45 to 75 char­ac­ters”, with 66 as the ​“sweet spot” (this includes let­ters and spaces).

This can be eas­i­ly achieved with the ch unit. So, max-inline-size: 66ch on text block ele­ments (p, ul, ol, etc.) should work. What I’ve found, though, is that if you count ​’em, you tend to get more than 66 let­ters and spaces. Why? Well, the ch unit is based on a spe­cif­ic char­ac­ter: the zero (0). So, if you do want 66 actu­al char­ac­ters, drop the num­ber down a bit. I go for 60.

For a lit­tle tighter con­trol, I use the min() func­tion. I don’t want text to go past a cer­tain point, even if it hasn’t reached the max­i­mum line length char­ac­ter-wise. On my web­site, for exam­ple, the intro­duc­to­ry para­graph is scaled up from oth­er para­graphs. The ch width on its own would mean that it looks ​“fat­ter” than oth­er para­graphs. I don’t want that, so I reach for:

:where(p, ul, ol) {
  max-inline-size: min(66ch, var(--prose-block-width));
}

The min() func­tion here choos­es whichev­er is the small­er cal­cu­lat­ed val­ue. For the intro­duc­to­ry para­graph, it’s like­ly to be the --prose-block-width cus­tom prop­er­ty. For reg­u­lar para­graphs, it’s 66ch. On mobile, the text defaults to the width of the avail­able space.

Wrap­ping

Typog­ra­phy on the web has become a lot more pow­er­ful in the last cou­ple of years. It’s not print design (and it can’t be), but some fea­tures of print typog­ra­phy have been dif­fi­cult to get right on the web. One of these is wrapping.

In print, you might have heard of wid­ows, orphans and runts.

  • A wid­ow is a sin­gle line of a para­graph at the top of a page or col­umn, sep­a­rat­ed from the rest of the paragraph.
  • An orphan is a sin­gle line of a para­graph at the bot­tom of a page or col­umn, with the rest of the para­graph on the next page or column.
  • A runt is a sin­gle word on a line of its own at the end of a paragraph.
Three columns of text. A widowed line of text appears on its own at the top of the second column. An orphaned line of text appears on its own at the end of the second column. And at the end of the third column is a line with one single word: the runt.

How widows, orphans and runts appear in unmodified text blocks.

Solv­ing these on the web is dif­fi­cult because the width of para­graphs (as men­tioned above) is not some­thing you have much con­trol over.

Wid­ows and orphans are only real­ly an issue when you’re using mul­ti­col­umn lay­outs or print­ing a page. There are CSS prop­er­ties you can apply to your stylesheet, though, to ensure these won’t be a problem:

:where(p) {
  orphans: 2;
  widows: 2;
}

When it comes to the ​“runt”, this is some­thing you might want to tack­le. The text-wrap prop­er­ty has a cou­ple of new val­ues that can help with this.

text-wrap: balance looks at your lines of text and attempts to ​“bal­ance” them; i.e., it tries to make each line take up rough­ly the same amount of space.

text-wrap: pretty is a lit­tle more vague, but it will try to pre­vent sin­gle-word runts from sit­ting on their own in the last line of a block of text.

Before going fur­ther, it’s worth point­ing out that both of these can be com­pu­ta­tion­al­ly expen­sive. text-wrap: balance should only be used on short blocks of text, and text-wrap: pretty should be reserved for pages where qual­i­ty is more impor­tant than speed.

My rule of thumb is to use text-wrap: balance for head­ings and sum­ma­ry text (like the index cards on the home­page of my site). Keep text-wrap: pretty for p tags on blog pages.

I would say, though, use these with care. Dif­fer­ent browsers treat them dif­fer­ent­ly, so test well!

Line Spac­ing

Line height is the web’s take on ​“lead­ing” (pro­nounced ​“led-ing”, not ​“leed-ing”). Lead­ing orig­i­nates from the prac­tice of putting lit­tle bits of lead between lines of text. On the web, though, this is a lit­tle dif­fer­ent. Line height is the space in which let­ters sit, rough­ly ver­ti­cal­ly cen­tred. It pro­vides a buffer above and below the text.

Choos­ing a line height depends on con­text. Much like the type scale in the pre­vi­ous instal­ment, I like to use a ratio for dif­fer­ent line heights. Line-height val­ues them­selves should be unit­less (they don’t have to be, but I’d strong­ly rec­om­mend it). For exam­ple, line-height: 1.6 is 1.6 times the size of the text it contains.

round(calc(var(--base-line-height) * pow(var(--line-height-ratio), var(--n))), 0.01);

The above func­tion, like our text-size approach, takes a base line-height val­ue (e.g., 1.6) and mul­ti­plies it by the step ratio (e.g., Major Sec­ond, 1.125) to the pow­er of the step num­ber. The round() func­tion then rounds it to the near­est hundredth.

The result­ing line heights would be:

:root {
  --line-height-1: 1.8;
  --line-height-0: 1.6;
  --line-height--1: 1.42;
  --line-height--2: 1.26;
  --line-height--3: 1.12;
  --line-height--4: 1.00;
}
A block paragraph of dummy text repeated 5 times, with each successive block possessing a tighter line height.

How a line height scale can change the rhythm of a paragraph.

From these, you can decide which texts get which line heights.

WCAG Suc­cess Cri­te­ri­on 1.4.12 uses a line height of at least 1.5 times the font size as a test val­ue for body text. I try to be a lit­tle more gen­er­ous and use 1.6. This also feels har­mo­nious with the 16px base size for text (the brows­er default).

Head­ings and microcopy 

For head­ings and micro­copy, choose a tighter line height; for dis­play head­ings like the one at the top of this arti­cle, go small­er again. Because you’re using ratios, line height should scale with your text.

Para­graph Spacing 

WCAG Suc­cess Cri­te­ri­on 1.4.12 also uses para­graph spac­ing of at least twice the font size as a test value.

Ver­ti­cal rhythm is real­ly impor­tant, espe­cial­ly in arti­cles like this. My approach is to make the spac­ing below para­graphs, list blocks (ul and ol) and head­ings the same. Use your judge­ment here, but con­sis­ten­cy is key. On this page, I use 1.25rem for bot­tom mar­gins and half that amount for list items (li).

The space above head­ings, though, is a lit­tle dif­fer­ent. The law of prox­im­i­ty means that head­ings should be clos­est to the para­graphs they’re con­nect­ed to. Rather than eye­balling it, use one val­ue (like 1.5em). em units are handy here, as they allow the space to adjust depend­ing on your head­ing size. Larg­er h2s, for exam­ple, will have a bit more breath­ing space above them than h3s.

Let­ter Spacing 

Okay, we’re approach­ing the end. It’s been quite a ride! There are just a cou­ple of quick ones left. Let­ter spac­ing is prob­a­bly some­thing you don’t both­er with that often, and most of the time you don’t need to. CSS allows you to set let­ter-spac­ing to a pos­i­tive or neg­a­tive val­ue in any unit, with the prop­er­ty default­ing to zero (0).

There are times, though, when a tweak is use­ful. If you have a token sys­tem, include a mini-ramp of let­ter-spac­ing val­ues for ease of access.

// Letter spacing

--typography-spacing-tight: -0.0375em;
--typography-spacing-compact: -0.025em;
--typography-spacing-normal: 0em;
--typography-spacing-loose: 0.05em;
--typography-spacing-wide: 0.125em;
The word Spacing repeated 4 times. Each one has a different letter spacing.

The difference a change in letter spacing can make to a word.

When it comes to head­ings, larg­er titles can be visu­al­ly improved with tighter spac­ing between let­ters. Sim­i­lar­ly, you may have small head­ings — per­haps divider head­ings in your nav­i­ga­tion set in small caps. Slight­ly loos­er spac­ing can pro­vide a lit­tle extra readability.

Word Spac­ing

Final­ly, word spac­ing. This is some­thing you’ll rarely need. My only sug­ges­tion here is for dis­play titles where you may have tight­ened the spac­ing between let­ters: a lit­tle extra spac­ing between words can add a bit of polish.

Back to top

See also…

  • Opinionated Typography: Scale

    Modernise web typography by combining CSS math functions like pow() and progress() to create mathematically sound, fully fluid font-size scales.