# How normalize.css Fixes Line-Height Issues for `sub` and `sup` Elements

> normalize.css fixes sub and sup line-height by setting line-height to 0 and reducing font-size to 75% for consistent vertical rhythm.

- Repository: [Nicolas Gallagher/normalize.css](https://github.com/necolas/normalize.css)
- Tags: deep-dive
- Published: 2026-03-07

---

**normalize.css prevents `sub` and `sup` elements from disrupting vertical rhythm by setting `line-height` to `0`, reducing `font-size` to `75%`, and applying relative positioning with specific vertical offsets.**

The [`necolas/normalize.css`](https://github.com/necolas/normalize.css/blob/main/necolas/normalize.css) repository provides a modern, HTML5-ready alternative to CSS resets, and its handling of `normalize.css line-height` for superscripts and subscripts ensures consistent typography across all browsers. By examining the source code at lines 125–138 of [`normalize.css`](https://github.com/necolas/normalize.css/blob/main/normalize.css), we can see exactly how these normalization rules eliminate the extra whitespace that typically surrounds these elements.

## The Line-Height Problem with `sub` and `sup` Elements

By default, browsers render `sub` and `sup` elements with styling that increases the height of their containing line boxes. This happens because default user agent styles apply a raised or lowered baseline shift while maintaining the element's full text metrics, causing adjacent lines to appear farther apart than intended. The result is broken vertical rhythm—particularly noticeable in paragraphs containing mathematical notation, chemical formulas, or ordinal indicators like "2<sup>nd</sup>".

## How normalize.css Resolves the Issue

The stylesheet applies a coordinated set of five CSS declarations to neutralize the spacing impact while preserving the visual positioning of the glyphs.

### Font Size Reduction

The rule first scales the glyphs proportionally smaller to ensure they do not dominate the text visually. Setting **`font-size: 75%`** makes the superscript or subscript characters three-quarters the size of the parent text, establishing a clear hierarchical relationship without requiring hardcoded pixel values.

### Zero Line-Height Declaration

The critical fix for the spacing issue is **`line-height: 0`**. This declaration removes the element's contribution to the line box calculation entirely, preventing the browser from allocating extra vertical space for the raised or lowered text. According to the source comments in [`normalize.css`](https://github.com/necolas/normalize.css/blob/main/normalize.css), this specifically targets the cross-browser inconsistency where these elements otherwise "affect the line height."

### Relative Positioning and Vertical Offsets

With **`position: relative`**, the elements establish their own positioning context without removing them from the document flow. The stylesheet then applies precise `em`-based offsets:
- **`sub { bottom: -0.25em; }`** – moves the subscript down by one-quarter of its font size
- **`sup { top: -0.5em; }`** – moves the superscript up by half its font size

These values, combined with **`vertical-align: baseline`**, create the illusion of raised or lowered text while the element itself technically remains on the baseline, contributing zero height to the line.

## The Source Code Implementation

The complete rule set appears in the core stylesheet at lines 125–138:

```css
/* 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;
}

```

This implementation in [`necolas/normalize.css`](https://github.com/necolas/normalize.css/blob/main/necolas/normalize.css) ensures that whether a user views your content in Chrome, Safari, Firefox, or Edge, the vertical spacing remains mathematically consistent and visually harmonious.

## Practical Implementation

Without normalization, standard HTML produces uneven line spacing:

```html
<p>H<sub>2</sub>O is water. 2<sup>nd</sup> place.</p>

```

The default browser styling adds extra leading above lines containing `sup` elements and below lines containing `sub` elements. Including the normalize.css file eliminates this behavior:

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

```

With the stylesheet applied, all lines maintain identical height regardless of subscript or superscript content, preserving the intended typographic grid.

## Summary

- **normalize.css** targets `sub` and `sup` elements at lines 125–138 of the main stylesheet to eliminate cross-browser line-height inconsistencies.
- **`line-height: 0`** is the primary mechanism that prevents these elements from expanding their containing line boxes.
- **`font-size: 75%`** ensures proportional scaling while **`position: relative`** enables precise vertical nudging without affecting layout flow.
- The combination of `bottom: -0.25em` for subscripts and `top: -0.5em` for superscripts achieves the visual effect while maintaining strict vertical rhythm.

## Frequently Asked Questions

### Why does normalize.css set line-height to 0 for sub and sup elements?

Setting `line-height: 0` removes the element's strut from the line box calculation, ensuring that the raised or lowered glyphs do not force the browser to allocate additional vertical space for the line. This prevents the "gap" that normally appears between text lines when these elements are present.

### What is the default browser behavior for sub and sup elements?

Default user agent stylesheets typically apply `vertical-align: sub` or `vertical-align: super` along with a reduced font size, but they maintain a positive line-height value. This causes the element to reserve space as if it were full-height text, creating uneven spacing in the paragraph.

### How do the vertical offset values work in normalize.css?

The stylesheet uses `em` units relative to the element's own font size. Because the font size is already reduced to 75% of the parent, a value like `-0.5em` for `sup` moves the element up by half of its reduced height, while `-0.25em` for `sub` moves it down by a quarter. This creates the optical illusion of baseline shifting without affecting the CSS line box.

### Can I override these styles if I need different positioning?

Yes, you can override these rules by declaring more specific CSS selectors after including normalize.css. However, maintain the `line-height: 0` declaration if you wish to preserve consistent vertical spacing; changing this value will reintroduce the line-height issues the library is designed to prevent.