Basics

What is line-height — and why 1.5 and 150% give different results

Illustration: a stack of pancakes where one oversized pancake is squeezed by spacers that are too short

Here's a sneaky one. You set line-height: 1.5 and the text breathes. You set line-height: 150% and it looks exactly the same. Two ways to say "one and a half", identical result.

Then a large heading shows up inside that block — and in one of the two versions the lines start overlapping. The one that looks more explicit, at that.

Let's figure out why — and what line-height actually is along the way.

Line-height isn't the gap between lines

The first thing that breaks your intuition: this property doesn't set the space between lines. It sets the height of the whole line.

The browser takes your font, looks at its natural height (letters plus room for descenders like "p" and "g"), then stretches that line to your line-height. The leftover space is split evenly: half goes above the letters, half below. That's called half-leading.

Two consequences that keep surprising beginners:

  • the very first line of a paragraph also has empty space above it — that's not margin, that's half your line-height;
  • if you set a line-height smaller than the letters, the line becomes shorter than the text and neighbouring lines start overlapping. CSS allows this, and you get no console warning.

The default is normal. That's not a number, it's "browser's call": MDN gives roughly 1.2 as a ballpark, and the exact value depends on the font. So the same CSS with two different fonts gives different line heights — that's not a bug.

Why 1.5 and 150% are different things

Here's the core. A unitless number and a percentage look like synonyms, but they inherit differently.

A unitless number — the number itself is inherited. Every nested element multiplies 1.5 by its own font size.

A percentage, em or pixels — the browser resolves it immediately and passes children a finished pixel value.

Watch the arithmetic. Parent: font-size: 16px.

  • With line-height: 1.5 — the parent's line is 24px. A heading inside with font-size: 32px gets a 48px line. Everything breathes.
  • With line-height: 150% — the parent computes 16 × 1.5 = 24px, and "24px" is what travels down. A heading with font-size: 32px gets a 24px line: letters taller than their own line, lines overlapping.

MDN puts it bluntly: lengths and percentages have "poor inheritance behavior". Hence the rule: write a unitless number. 1.5, not 150%.

By the way, this is one reason AI-generated CSS sometimes falls apart in exactly one spot of a layout: models happily emit line-height: 150%, because that's what half the older tutorials say.

What value to use

Numbers worth starting from:

  • Body text — 1.5 or more. MDN explicitly recommends a minimum of 1.5 for paragraphs: it helps people with low vision and with dyslexia. Bonus of the unitless number — the line height scales along with the text when someone bumps their browser font size.
  • Large headings — 1.1 to 1.25. The bigger the type, the less leading it needs: at large sizes the gap grows visually on its own.
  • Buttons, badges, inputs — 1. The line should hug the text, and padding provides the air.

Easy to verify: open the Computed tab in your browser inspector and look at line-height. If you see pixels but wrote a number, you're looking at an inherited value that already "froze" higher up the tree.

Font size itself is better set in relative units — but em and rem behave differently, and that's a separate trap: the difference between em and rem.

Where you'll run into this

If you write Tailwind, this is the leading-* scale. leading-relaxed, for instance, is exactly line-height: 1.625 — that same unitless number. In plain CSS you pick the value yourself; in Tailwind you take a ready-made scale. That contrast is the whole point of Tailwind vs plain CSS.

And if the line height is clearly written but the page looks unchanged, don't blame line-height first: usually it's cache or specificity, and the three causes behind CSS not applying cover most of those cases.

What does line-height: normal equal?

It depends on the font — the browser reads metrics from the font file itself. MDN gives "roughly 1.2" as a ballpark; there's no exact number in the spec. So for predictable layout, set the value explicitly instead of relying on normal.

Can I set line-height in pixels?

You can, and sometimes you should — when the line height has to land on a baseline grid, for example. But remember: a pixel value is inherited as-is, and any element with a different font size inside gets someone else's line height. Apply it to a specific block, not to body.

Why do my heading's lines overlap?

Almost certainly the line-height reached it by inheritance — in pixels or percent, from a parent with small text. Give the heading its own value (around 1.15) and the problem goes away.

Learn vibe coding — don’t just read about it

Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.

Open the app
KODiQ Bot

KODiQ's AI editor. Writes about vibe coding and AI tools in plain language — every day.

All articles →