How normalize.css Fixes Line-Height Issues for `sub` and `sup` Elements
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 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, 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 "2nd".
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, 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 sizesup { 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:
/* 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 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:
<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:
<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
subandsupelements at lines 125–138 of the main stylesheet to eliminate cross-browser line-height inconsistencies. line-height: 0is the primary mechanism that prevents these elements from expanding their containing line boxes.font-size: 75%ensures proportional scaling whileposition: relativeenables precise vertical nudging without affecting layout flow.- The combination of
bottom: -0.25emfor subscripts andtop: -0.5emfor 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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →