You should be using unitless values for line-height

July 21, 2025

1,449 words

Post contents

Back when I was a designer, I was curious why Adobe programs defaulted to a specific line height when selecting “auto” for leading (fancy designer word for line-height). The default seemed to be 120% of the font size, a value that aligns with common typographic standards, including those referenced in some ISO guidelines (e.g., ISO 215 for document layout, though not a direct specification for software defaults). These standards often suggest values around 120% for 'single-spaced' lines, 150% for 'line and a half,' and 200% for 'double-spaced' lines. I’m sure this brings you back to your years as a student when teachers asked you for double spaced papers so they could use their evil red pen to tell you how bad your essay was (lulz). Well, this was the convention used in MS Word when you selected that option! Apparently, Word uses some ”secret sauce formula” for calculating this, while other software is more straightforward, but we won’t get into that.

What does this mean to me if I’m a developer? It means that you have a baked-in, very simple way to adhere to this standard: unitless values. In CSS, when you use a unitless value for line-height you are dynamically calculating the line height based on the element’s font size. So, when you set line-height: 1.2 you are setting the line height to 120% of the font size, which is the standard for single spaced lines!

Unexpected behavior of using rem and em

You may already know rem values for font sizes are preferred so your app’s font size will scale with the user agent’s font size. I believe this leads to the notion that you should be using rem with line height as well. This is not always the case. Using rem units may lead to unexpected behavior:

<style>	html {		font-size: 16px; /* Simulated user agent style */	}		body {		font-size: 1rem; /* 16px */		line-height: 1.5rem; /* computed height: 24px (1.5 * 16px) */	}		h1 {		font-size: 4rem; /* computed height: 24px (inherited) */	}		p {		font-size: 2rem; /* computed height: 24px (inherited) */	}</style><body>	<h1 class="heading">This ackshully is not a long heading at all</h1>  <p class="text">    Lorem Ipsum is simply dummy text of the printing and typesetting    industry. Lorem Ipsum has been the industry's standard dummy text ever    since the 1500s, when an unknown printer took a galley of type and    scrambled it to make a type specimen book. It has survived not only five    centuries, but also the leap into electronic typesetting, remaining    essentially unchanged. It was popularised in the 1960s with the release    of Letraset sheets containing Lorem Ipsum passages, and more recently    with desktop publishing software like Aldus PageMaker including versions    of Lorem Ipsum.  </p></body>

As you can see, the computed line height for the p and h1 is inherited from body which is calculated based on the user agent font size therefore too small and an accessibility violation.

The obvious downside of using px values is that line height will not be dynamic, but what about em values? Wouldn’t that work since they are not tied to the root html styles? Just don’t do it.

Let's try unitless:

<style>	html {		font-size: 16px; /* Simulated user agent style */	}		body {		font-size: 1rem; /* 16px */		line-height: 1.5; /* computed height: 24px (1.5 * 16px) */	}		h1 {		font-size: 4rem; /* computed height: 96px (1.5 * 64px) */	}		p {		font-size: 2rem; /* computed height: 48px (1.5 * 32px) */	}</style><body>	<h1 class="heading">This ackshully is not a long heading at all</h1>  <p class="text">    Lorem Ipsum is simply dummy text of the printing and typesetting    industry. Lorem Ipsum has been the industry's standard dummy text ever    since the 1500s, when an unknown printer took a galley of type and    scrambled it to make a type specimen book. It has survived not only five    centuries, but also the leap into electronic typesetting, remaining    essentially unchanged. It was popularised in the 1960s with the release    of Letraset sheets containing Lorem Ipsum passages, and more recently    with desktop publishing software like Aldus PageMaker including versions    of Lorem Ipsum.  </p></body>

Ah, much better! The only thing we changed was line-height: 1.5rem to line-height: 1.5

Accessibility

Does this have anything to do with accessibility? It most certainly does! Using unitless values will scale the line height not only with an increase in user agent font size, but also with zoom. This is huge, as one of the most common techniques used to better read web pages is to zoom the browser in. Go ahead and try it in your browser.

WCAG provides us with an advisory technique for line spacing (if you don’t know the difference between sufficient and advisory or what they mean, read about them here) that says:

”Many people with cognitive disabilities have trouble tracking lines of text when a block of text is single spaced. Providing spacing between 1.5 to 2 allows them to start a new line more easily once they have finished the previous one.”

After reading this, I updated a site I was working on to use 1.5 (line and a half) and hated it. It felt like it changed my whole site and all the body text had way too much spacing. Not really knowing how to feel I closed my laptop and thought I’d ponder the idea for a day. When I came back I hated it much less—in fact I even liked it. I feel like sometimes when we get used to doing something less than ideal, or even get used to things that aren’t considered a best practice, we set ourselves up for failure in the long run when we discover there’s a better way of doing things—or even a correct way! I really think this outlines the importance of good foundational knowledge not only regarding something as simple as line-height, but literally in everything that we do. Moving forward, I think I will set all my body text’s line height to 1.5 and take the W on a solid WCAG advisory. Just one small step closer to that AAA accessibility rating.

The most important thing here is that we are not overlapping or overflowing text, making it unreadable. This would be a failure of F104.

Further reading: https://www.w3.org/WAI/WCAG22/Understanding/text-spacing

Sum it all up

This is not fancy. This is not super smart. This is a very simple and straightforward methodology to handle a facet of what should be a very simple and straightforward thing: Displaying text. I hope all of you reading this understand it and will go out there and feel confident that the text on your site is readable for all viewers!

If you're a fan of Tailwind, here's a custom TW4 theme to get you started:

// tailwind.config.js/** @type {import('tailwindcss').Config} */export default {  content: [    './index.html',    './src/**/*.{js,ts,jsx,tsx}',  ],  theme: {    extend: {      // Define a custom font size scale with associated unitless line heights      fontSize: {        // Base font size for body text        'base': ['1rem', { lineHeight: '1.5' }], // 16px font, 1.5 (unitless) line-height = 24px        // Larger font sizes for headings, etc.        'lg': ['1.125rem', { lineHeight: '1.5' }], // 18px font, 1.5 line-height = 27px        'xl': ['1.25rem', { lineHeight: '1.5' }],  // 20px font, 1.5 line-height = 30px        '2xl': ['1.5rem', { lineHeight: '1.4' }],   // 24px font, 1.4 line-height = 33.6px (slightly tighter for larger headings)        '3xl': ['1.875rem', { lineHeight: '1.35' }], // 30px font, 1.35 line-height = 40.5px        '4xl': ['2.25rem', { lineHeight: '1.3' }],  // 36px font, 1.3 line-height = 46.8px        '5xl': ['3rem', { lineHeight: '1.25' }],    // 48px font, 1.25 line-height = 60px        '6xl': ['3.75rem', { lineHeight: '1.2' }],  // 60px font, 1.2 line-height = 72px        '7xl': ['4.5rem', { lineHeight: '1.15' }],  // 72px font, 1.15 line-height = 82.8px        '8xl': ['6rem', { lineHeight: '1.1' }],     // 96px font, 1.1 line-height = 105.6px        '9xl': ['8rem', { lineHeight: '1' }],       // 128px font, 1.0 line-height = 128px (very tight, for very large display text)      },      // Define a line-height scale consisting only of unitless values      // This allows for explicit line-height control when fontSize doesn't provide enough granularity.      lineHeight: {        'none': '1',       // No spacing        'tight': '1.15',   // A bit tighter than default        'snug': '1.25',    // Slightly snug        'normal': '1.5',   // Recommended for body text        'relaxed': '1.75', // More relaxed        'loose': '2',      // Double-spaced        // Custom values, e.g., for specific design needs        '1.2': '1.2',        '1.3': '1.3',        '1.4': '1.4',        '1.6': '1.6',        '1.8': '1.8',      }    },  },  plugins: [],}

Subscribe to our newsletter!

Subscribe to our newsletter to get updates on new content we create, events we have coming up, and more! We'll make sure not to spam you and provide good insights to the content we have.