The Difference Between CSS line-height Numbers and Percentages, and Best Practices

CSS line-height: unitless numbers inherit ratios per element, while percentages inherit fixed computed values.
CSS line-height behaves differently with unitless numbers vs. percentages. Unitless numbers (e.g., 1.5) inherit the ratio, letting each element recalculate based on its own font-size. Percentages (e.g., 150%) compute a fixed value on the declaring element and pass that unchanged to descendants, causing layout anomalies when child elements have different font sizes. Always prefer unitless numbers for adaptive, proportional line spacing.
A CSS Detail Overlooked for Years
Even developers who've been writing CSS for years may have misconceptions about a key behavior of line-height. Recently, a senior front-end developer admitted that he always thought he understood line-height, until he recently realized that unitless numbers and percentages behave differently when used with line-height.
This difference isn't obvious in most cases, but it becomes apparent when dealing with nested text of different font sizes. Understanding this distinction can help you avoid some hard-to-debug CSS layout bugs.
To understand the essence of this issue, you first need to understand CSS's inheritance mechanism. CSS Inheritance is one of the most fundamental design concepts of Cascading Style Sheets. Not all properties are inherited—box model properties like border, margin, and padding don't inherit by default, while typography-related properties like color, font-family, and line-height are automatically passed from parent to child elements. Inheritance comes in two flavors: inheriting the "specified value" or inheriting the "computed value." The unitless number for line-height happens to be one of the rare cases where the specified value is inherited, making it a special and important case in the CSS specification.

Unitless Numbers vs. Percentages: What's the Core Difference
Recommended Approach: Unitless Numbers
Most developers are accustomed to setting line height like this:
body {
line-height: 1.5;
}
The 1.5 here is a unitless number, typically set on body for global inheritance. Its behavior is: each element recalculates the line height based on its own font-size.
In other words, the "ratio" of 1.5 is what gets inherited, not a computed pixel value. Child elements receive the "multiplier 1.5" and multiply it by their own font size to get their own line height.
In the CSS2.1 specification (and the subsequent CSS Inline Layout Module Level 3), the value types for line-height are explicitly distinguished as: normal, <number>, <length>, and <percentage>. The spec specifically states that when the value is a <number>, the "used value" is that number multiplied by the element's own font-size; whereas when the value is a <length> or <percentage>, the computed value is already determined as an absolute length on the declaring element, and descendant elements inherit this absolute length rather than the ratio factor. This design is intentional, aimed at providing developers with two different line-height control strategies.
The Pitfall: Percentages
If you use a percentage instead:
body {
line-height: 150%;
}
On the surface it looks almost identical, but the inheritance mechanism is completely different. When you use a percentage (or other unit-based values like px or em), the browser calculates the line height into a fixed value on the declaring element, then passes this already-computed specific value down to all child elements.
This means that if a child element has a different font size from its parent, the line height it inherits is still the fixed value calculated based on the parent's font size—it won't be recalculated based on its own font size.
Verifying line-height Inheritance Behavior with DevTools
You can visually verify this difference using browser developer tools. Modern browser DevTools provide a "Computed" panel that shows the final property values applied to an element after cascading, inheritance, and computation. Unlike the "Styles" panel which shows rule declarations, the Computed panel shows the absolute values the browser actually uses for rendering. For line-height, it displays the final pixel value, allowing developers to visually compare the actual line heights of different elements and quickly determine whether there's an inheritance anomaly. Chrome DevTools also supports clicking on property values in the Computed panel to trace back to their source rules, which is particularly efficient for debugging inheritance chain issues.
When using unitless numbers, selecting different paragraphs reveals that line height is independently calculated for each element:
- A paragraph with a larger font size has a computed line height of approximately 38.8px
- A paragraph with a smaller font size has a computed line height of approximately 23.2px

This makes perfect sense—an element with a smaller font size multiplied by 1.5 naturally yields a smaller line height. The "odd numbers" like 38.8 and 23.2 appear because clamp() fluid font sizing is being used, where the font size itself isn't a whole number.
clamp() is a CSS math function with the syntax clamp(minimum, preferred, maximum). In Fluid Typography, developers often set font-size to something like clamp(1rem, 2.5vw, 2rem), allowing the font size to scale smoothly as viewport width changes, rather than relying on traditional media query breakpoint jumps. A side effect of this approach is that the font size isn't an integer pixel value at most viewport widths, so multiplying by line-height also produces decimal pixel line heights.

Line Height Anomalies Caused by Percentages
The critical comparison appears when using percentages. An element with a noticeably smaller font size still shows a line height of 38.8px—identical to the large font size element.

The reason is: percentages complete all the math on the element where they're declared, producing a fixed line height value that gets inherited unchanged by all descendant elements. So small-sized text ends up with a line height calculated for large-sized text, visually resulting in excessive line spacing and disproportionate layout.
Why line-height Should Use Unitless Numbers
From the comparison above, the conclusion is clear:
- Unitless numbers: The "ratio" is inherited, and each element recalculates based on its own
font-size, keeping typographic proportions consistently harmonious - Percentages / unit-based values: The "computed result" is inherited, and once a child element's font size changes, the line height won't adjust accordingly, easily causing layout anomalies
This is why the CSS community and W3C specification have long recommended using unitless numbers as the preferred way to set line-height. It's not only more concise but, more importantly, aligns with the intuitive expectation that "line height should adapt with font size."
It's worth noting that this principle isn't unique to line-height. In CSS, similar "unitless vs. unit-based" behavioral differences also appear in other contexts, such as the zoom property and certain SVG attributes. Understanding the underlying logic of "whether what's inherited is a ratio or a computed value" helps you apply the same reasoning when encountering similar issues.
Practical Recommendations for Setting line-height
- Use unitless numbers by default: Write
line-height: 1.5inbodyor global styles, letting the entire page's line height ratio automatically adapt to various font sizes. - Avoid percentages or fixed units: Unless you specifically need to "lock in" a particular line height value (e.g., for precise vertical centering of text in a fixed-height button), don't use
150%or24pxstyle declarations. - Pay attention to fluid font size scenarios: When using
clamp()or other fluid font sizing, unitless line height ensures line spacing always matches the real-time font size—this is especially important. As responsive design becomes increasingly prevalent, fluid typography has become a mainstream trend, and pairing it with unitlessline-heightensures text maintains good readability at any viewport width. - Use DevTools for debugging: If you notice odd line spacing somewhere, select the element and check the "Computed" values—this often immediately identifies whether a line-height inheritance issue is the cause. Pay particular attention to comparing parent and child elements' computed line-height values—if a child element has a noticeably different font size but the same line height, it's most likely caused by percentage or fixed-unit inheritance.
- Notes on CSS Reset/Normalize: Many popular CSS Reset libraries (such as modern-normalize) already use unitless numbers for
line-heightby default. If your project uses a custom global style reset, make sure to check whether itsline-heightdeclaration is reasonable.
Summary
line-height may seem like the most basic CSS property, but it harbors an easily overlooked inheritance behavior difference. Unitless numbers inherit the ratio and calculate per element; percentages inherit an already-computed fixed value. Understanding this not only helps avoid hard-to-debug layout bugs but also reminds us: even with technologies we've been familiar with for years, it's worth occasionally revisiting the fundamentals.
From a broader perspective, many CSS "gotchas" stem from developers lacking a clear mental model of "when values are computed and in what form they're inherited." The line-height case is an excellent teaching example—it reminds us that declarations that appear equivalent on the surface (1.5 vs 150%) can have entirely different semantics under the browser's cascading and inheritance mechanisms.
Key Takeaways
Related articles

Meta Muse Glimmer 30B In-Depth Review: Impressive Visual Understanding, Low Local Deployment Barrier
Meta Muse Glimmer 30B hands-on review: 29.6B dense model with Apache 2.0 license, impressive visual understanding, 128K context, runs on 24GB VRAM. Benchmarks, multimodal tests, and limitations.

Netflix GenRec: How an LLM-Native Recommendation System Is Reshaping Personalized Recommendations
Deep analysis of Netflix GenRec's generative recommendation system, covering Semantic IDs, LLM-native architecture, and the paradigm shift from discriminative to generative recommendation.
Real-Time Ship Tracking in the Strait …
Real-Time Ship Tracking in the Strait of Hormuz: How AIS Data Became a Window into Geopolitical Risk
Deep dive into the Strait of Hormuz live ship tracking project's technical principles and geopolitical value. Learn how AIS data enables strait traffic visualization and its role in global energy security monitoring.