What is CSS Line Height?
The line-height CSS property sets the height of a line box in horizontal writing modes. It directly impacts how readable your content is across different screen sizes and devices. Whether you're building a Next.js marketing site or a complex web application, understanding line-height determines whether your text feels comfortable or cramped.
Key points covered:
- How line-height affects text layout and readability
- All value types: normal, unitless numbers, em, px, percentages
- Recommended line-height ranges for different content types
- Accessibility requirements (WCAG 2.2)
- Implementation in modern CSS frameworks like Tailwind CSS
The line-height property is fundamental to typography on the web. When you set line-height, you're controlling the space between lines of text--historically known as "leading" in traditional typesetting. This space appears both above and below each line, creating the vertical rhythm that readers unconsciously rely on when consuming content.
Browsers use a default value of normal for line-height, which typically computes to approximately 1.2 times the font size. However, this default varies based on the font-family being used, making explicit line-height declarations essential for consistent typography across your website. For a deeper dive into CSS fundamentals, explore our guide on CSS selectors to build a solid foundation for your stylesheets.
CSS Line Height Values: A Complete Reference
The normal Keyword
The normal keyword tells the browser to use a "reasonable" value based on the font size and font family. Desktop browsers typically use a default of roughly 1.2 depending on the element's font-family. MDN Web Docs confirms this variability in default behavior.
/* Browser-dependent, typically ~1.2 */
line-height: normal;
Since normal is browser-dependent, it's not recommended for production websites where consistent typography is essential. Different browsers and font combinations will produce different results.
Unitless (Number) Values
Unitless values are the recommended method for defining line-height because child elements inherit the raw number value rather than the computed pixel value. This means each element calculates its line-height based on its own font-size, creating more predictable typography that scales properly throughout your component hierarchy.
/* Preferred method - inherits as number, scales with font-size */
body {
line-height: 1.5;
}
p {
line-height: 1.6;
}
CSS-Tricks emphasizes that unitless values work because child elements inherit the raw number value rather than the computed pixel value. This is crucial for responsive and component-based architectures. When combined with CSS Flexbox, these scalable typography values help create consistent layouts across all screen sizes.
Length Values (px, em, rem)
Length values specify an exact line-height. While they provide pixel-perfect control, they can create issues with inheritance and responsiveness that make them problematic for modern web development.
/* Fixed pixel value - problematic for responsive design */
p {
line-height: 24px;
}
/* Relative to current font-size - can compound */
p {
line-height: 1.5em;
}
/* Root-relative - more predictable */
p {
line-height: 1.5rem;
}
MDN Web Docs warns that values given in em units may produce unexpected results due to how inheritance works with line-height. When you use em units, the value is calculated based on the inherited font-size, which can compound in nested elements.
Percentage Values
Percentage values are relative to the element's font size and can produce unexpected results due to inheritance complexities.
/* Percentage of the element's font-size */
p {
line-height: 150%; /* Computes to 1.5 times font-size */
}
Like em values, percentage values can create inheritance complications that make unitless numbers the safer and more maintainable choice for most projects.
Best Practices for Line Height in Modern Web Development
Recommended Line-Height Ranges
Based on typography research and industry best practices established by experts like Kevin Powell, these ranges work well for most websites:
| Content Type | Recommended Line-Height | Example |
|---|---|---|
| Body text | 1.4-1.6 | line-height: 1.5; |
| Headings | 1.1-1.3 | line-height: 1.2; |
| UI text | 1.3-1.5 | line-height: 1.4; |
| Accessibility minimum | 1.5+ | line-height: 1.5; |
Body text benefits from the 1.4-1.6 range because it provides enough space between lines for comfortable reading while maintaining visual cohesion. This range aligns with typography research showing optimal readability for extended text.
Headings typically look better with tighter line-heights (1.1-1.3) since their larger size requires less vertical space to feel balanced. Using body text line-height on headings creates excessive whitespace that disrupts the visual hierarchy.
The Unitless Advantage
The key advantage of unitless values becomes apparent in responsive and component-based architectures:
/* Good: Child elements calculate based on their own font-size */
.parent {
font-size: 18px;
line-height: 1.5; /* Child inherits 1.5 */
}
.child {
font-size: 24px;
line-height: inherits 1.5; /* Computes to 36px */
}
/* Problematic: Fixed values don't scale */
.parent {
font-size: 18px;
line-height: 27px; /* Child inherits 27px */
}
.child {
font-size: 24px;
line-height: inherits 27px; /* Fixed, not proportional */
}
This inheritance behavior makes unitless values essential for maintainable CSS architectures where typography scales across different component sizes and responsive breakpoints. For responsive typography that adapts to different devices, also review our guide on viewport configuration to ensure your typography works seamlessly across all screen dimensions.
Line Height in Next.js and Modern CSS Frameworks
Tailwind CSS Line Height
Tailwind CSS provides a comprehensive set of line-height utility classes that map directly to numeric values:
<!-- Tailwind utility classes -->
<p class="leading-tight">Tight line height (1.25)</p>
<p class="leading-snug">Snug line height (1.375)</p>
<p class="leading-normal">Normal line height</p>
<p class="leading-relaxed">Relaxed line height (1.625)</p>
<p class="leading-loose">Loose line height (2.0)</p>
You can also customize these values in your Tailwind configuration to match your design system:
// tailwind.config.js
module.exports = {
theme: {
extend: {
lineHeight: {
'body': '1.6',
'heading': '1.2',
}
}
}
}
CSS-in-JS Considerations
In component-based architectures like Next.js applications, line-height should be defined at the typography layer to ensure consistency across your design system:
// styled-components typography layer
const Text = styled.p`
font-size: 1rem;
line-height: 1.6; /* Unitless for scalability */
`;
const Heading = styled.h2`
font-size: 2rem;
line-height: 1.2; /* Tighter for headings */
`;
Performance Considerations
Line-height is a non-paint affecting property, meaning changes to it don't trigger layout recalculations for paint-only browsers. However, excessive line-height on large text blocks can increase memory usage for line box trees. Modern browsers handle line-height efficiently, but avoiding unnecessary values helps maintain performance at scale when building high-performance web applications.
Common Pitfalls and How to Avoid Them
Pitfall 1: Inheriting Fixed Values
Problem:
body {
line-height: 24px; /* Fixed value inherits down */
}
.small-text {
font-size: 12px;
/* Inherits 24px line-height = 2.0 effective ratio */
}
Solution:
body {
line-height: 1.5; /* Unitless scales properly */
}
.small-text {
font-size: 12px;
/* Inherits 1.5, computes to 18px */
}
Pitfall 2: Inconsistent Vertical Rhythm
When line-heights don't align, text can appear to "float" rather than establishing clear visual rhythm. The solution is to establish a base unit and ensure line-heights are multiples of that unit.
:root {
--baseline: 8px;
}
p {
font-size: 16px;
line-height: calc(var(--baseline) * 2); /* 16px */
}
This approach creates consistent vertical rhythm that improves both aesthetics and readability across your design system. For additional techniques on creating cohesive layouts, explore our guide to CSS Flexbox which complements proper typography with flexible layout capabilities.
Pitfall 3: Heading Line Height Too Loose
Headings typically display in larger sizes and require less line-height to look balanced.
Problematic:
h1 {
font-size: 3rem;
line-height: 1.5; /* Too loose for headings */
}
Better:
h1 {
font-size: 3rem;
line-height: 1.1; /* Tighter, more balanced */
}
| Value Type | Recommendation | Use Case |
|---|---|---|
| `normal` | Avoid in production | Browser-dependent |
| Unitless number | Preferred | All general use |
| `em` | Use sparingly | When specific proportions needed |
| `px` | Avoid | Not responsive |
| Percentage | Use sparingly | Legacy compatibility |
Frequently Asked Questions
Sources
- MDN Web Docs: line-height - Official documentation covering syntax, values, and accessibility guidelines
- CSS-Tricks: line-height - Practical guide emphasizing unitless line heights as the recommended approach
- Kevin Powell: Fix Your Line-Height - Typography research and recommended line-height ranges (1.4-1.6)
- Pimp My Type: Ideal Line Length & Line Height - Typography principles and readability guidelines