How To Fix Spacing Between Text Blocks When Using Tailwind CSS

  You block advertising 😢
Would you like to buy me a ☕️ instead?

Did you ever encounter the problem that the space between a text block and some other element seems wrong? For example, although we’ve added the same mt-4 to a text block and some images, the space between text and image looks much larger than the space between two images. So instead of mt-4 we try mt-3, but it just doesn’t work out. This happens because the same margin can look visually different if it separates text from some element instead of separating two non-text elements. After all, the line height of the text block adds additional spacing.

The problem in depth

Line height adding additional spacing is a known issue with CSS. When we apply a margin-top of 1em, we expect two elements to be separated by exactly 1em. And for elements with a solid background, a border, or for images, this is true. But not so for text blocks.

Spacing between text elements with and without capsize explained.

Same spacing, different visual results

Because text blocks have a visual height that does not match their effective height (line height), if we apply margin-top: 1em to a text block, the spacing is 1em + whatever the line height adds to it (which can be a lot, especially at large font sizes and line heights). Yet the visual size of a text block approximately equals the imaginary line at the top and bottom of uppercase letters.

Capsize to the rescue

Luckily, there is a technique we can use to deal with this problem: Capsize. Although we could use Capsize as is with Tailwind CSS, too, using a dedicated Tailwind plugin can make our lives easier.

And again, we’re lucky: there is a Tailwind plugin ready for us to use too: https://www.npmjs.com/package/tailwindcss-capsize

// tailwind.config.cjs
module.exports = {
  // ...
  plugins: [
    require('tailwindcss-capsize')({
      className: 'leading-trim',
    }),
  ],
};

I like to change the class name to leading-trim, but this is a matter of personal taste!

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .leading-trim {
    @apply font-sans text-base align-middle;
  }
}

By default, the plugin requires you to specify the font-family and font-size on every element you want to apply the leading-trim style to (e.g., <p class="leading-trim font-sans text-base">). I’m a fan of sensible defaults, so I extend the leading-trim class in my base styles so that it sets the most common styles by default. If I want to, I can override them: <p class="leading-trim text-lg">.

Using the leading-trim utility class

We’ve set up everything to add the leading-trim utility class to whatever text block we want. And I recommend adding it to every text block! That way, adding consistent spacing between (text) elements becomes much more intuitive.

<h1 class="leading-trim text-lg">Headline<h1/>
<p class="leading-trim">Paragraph</p>

Wrapping it up

Hopefully, one day we’ll have native support in CSS for leading-trim. But until the day arrives, using Capsize and the Capsize Tailwind plugin is a viable workaround.


Do you want to learn how to build advanced Vue.js applications?

Register for the Newsletter of my upcoming book: Advanced Vue.js Application Architecture.



Do you enjoy reading my blog?

You can buy me a ☕️ on Ko-fi!

☕️ Support Me on Ko-fi