CSS Line Height: The Complete Guide for Modern Web Development

Master the line-height property to create readable, accessible, and visually consistent typography. From basic syntax to advanced techniques for Next.js applications.

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 TypeRecommended Line-HeightExample
Body text1.4-1.6line-height: 1.5;
Headings1.1-1.3line-height: 1.2;
UI text1.3-1.5line-height: 1.4;
Accessibility minimum1.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 */
}
Quick Reference: Line Height Values
Value TypeRecommendationUse Case
`normal`Avoid in productionBrowser-dependent
Unitless numberPreferredAll general use
`em`Use sparinglyWhen specific proportions needed
`px`AvoidNot responsive
PercentageUse sparinglyLegacy compatibility

Frequently Asked Questions

Need Help with Your Web Development Project?

Our team builds custom websites with optimized typography, performance, and accessibility built in from the start. From design systems to responsive implementations, we ensure your typography works for every user.

Sources

  1. MDN Web Docs: line-height - Official documentation covering syntax, values, and accessibility guidelines
  2. CSS-Tricks: line-height - Practical guide emphasizing unitless line heights as the recommended approach
  3. Kevin Powell: Fix Your Line-Height - Typography research and recommended line-height ranges (1.4-1.6)
  4. Pimp My Type: Ideal Line Length & Line Height - Typography principles and readability guidelines