Why Does normalize.css Set `line-height: 0` on `sub` and `sup` Elements?

normalize.css sets line-height: 0 on sub and sup elements to prevent them from contributing extra vertical spacing to the line box, ensuring consistent paragraph rhythm while using relative positioning to visually raise or lower the glyphs without affecting surrounding text flow.

Default browser styles for superscript and subscript text often inject unwanted line-height expansion that breaks the vertical rhythm of paragraphs. The necolas/normalize.css project eliminates this cross-browser inconsistency by zeroing out the line height and compensating with precise relative offsets, preserving the intended typography of scientific notation, footnotes, and ordinal indicators.

The Typography Problem with Default sub and sup Styles

Browsers render sub and sup elements with smaller text sizes, but many default user agent stylesheets calculate the line height as if the glyphs occupy full ascender or descender space. This causes the parent line box to expand, creating uneven spacing between lines of text that disrupts the visual rhythm of paragraphs containing chemical formulas (H₂O), mathematical exponents (E=mc²), or ordinal numbers (2ⁿᵈ).

How normalize.css Fixes Line Height at Lines 125-138

The core stylesheet addresses this by applying a coordinated set of rules that isolate the visual presentation of these elements from the document’s flow metrics. According to the source code in normalize.css, the implementation spans lines 125-138:

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

Why line-height: 0 Is Critical

Setting line-height: 0 removes the element’s contribution to the line box’s strut height. In CSS inline layout, every inline element generates a content area that affects the minimum height of the line box. By forcing this value to zero, normalize.css ensures that sub and sup elements do not expand the parent container’s vertical dimensions, allowing the surrounding text to maintain its specified leading (line height) regardless of superscript or subscript presence.

Relative Positioning and Visual Offsets

The stylesheet pairs line-height: 0 with position: relative and specific directional offsets to achieve the visual effect without layout side effects. The vertical-align: baseline declaration keeps the element’s initial alignment point consistent with the parent text, while top: -0.5em (for sup) and bottom: -0.25em (for sub) physically shift the rendered glyphs to their expected positions. This technique works because relative positioning moves the visual box without altering the space the element occupies in the document flow.

Visual Comparison: With and Without normalize.css

Without the normalization rules, sub and sup elements create unwanted gaps:

<p>H₂O is water. 2<sup>nd</sup> place.</p>

Default browser behavior: The line containing the superscript or subscript expands vertically, causing uneven spacing between this line and adjacent lines.

With normalize.css included, the vertical rhythm remains intact:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<p>H₂O is water. 2<sup>nd</sup> place.</p>

Normalized behavior: The line height stays consistent; the superscript and subscript appear at the correct vertical positions without pushing surrounding lines apart, as the line-height: 0 declaration neutralizes their impact on the line box calculation.

Summary

  • Source Location: The normalization rules for sub and sup are defined at lines 125-138 in normalize.css.
  • Core Mechanism: line-height: 0 prevents these elements from expanding the parent line box, preserving paragraph rhythm.
  • Visual Compensation: Relative positioning with top: -0.5em and bottom: -0.25em provides the necessary vertical offsets without affecting surrounding text flow.
  • Cross-Browser Consistency: This approach eliminates rendering differences between Chrome, Firefox, Safari, and Edge.
  • Proportional Sizing: The font-size: 75% rule ensures glyphs remain proportional to the parent text while minimizing their layout footprint.

Frequently Asked Questions

Does line-height: 0 affect screen reader accessibility?

No. Screen readers announce the semantic meaning of sub and sup tags based on the HTML structure, not the CSS presentation. The line-height property is purely presentational and does not alter the accessibility tree or how assistive technologies interpret these elements as subscript or superscript text.

Why doesn't normalize.css use vertical-align: super or sub instead?

Browser implementations of vertical-align: super and vertical-align: sub vary significantly in their vertical displacement calculations and often still alter line height metrics in inconsistent ways. The explicit combination of line-height: 0 and relative positioning ensures pixel-perfect, uniform rendering across all modern rendering engines without relying on browser-specific keyword behaviors.

Can I override the offset values for tighter or looser spacing?

Yes. You can override the top: -0.5em (for sup) or bottom: -0.25em (for sub) declarations in your custom stylesheet after including normalize.css. However, you should generally preserve the line-height: 0 rule to maintain vertical rhythm; modifying only the top or bottom values adjusts the visual appearance without reintroducing line-height expansion.

Which browsers benefit from this normalization?

All modern browsers—including Chrome, Firefox, Safari, and Edge—historically exhibited slightly different line-height calculations for subscript and superscript elements. The rules in normalize.css lines 125-138 ensure uniform rendering across these engines, making this normalization relevant for any project supporting contemporary browser versions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →