Perfect Icon Alignment with Tailwind CSS and Line Height
Warning
This post is best viewed on desktop. It will work on mobile, but it may be hard to use the interactive code examples.
If you've been building UIs for any length of time, you've probably encountered the seemingly simple task of aligning an icon with some text. You know what I mean - those moments when you're building a navigation menu, a list of features, or a pricing card, and you just want the icon to sit perfectly with the text. Sounds easy, right?
Well, let's explore this journey together, looking at different approaches I've used over the years, and discover how the CSS class lh
can now be used in Taillwind V4, to finally solves this age-old challenge.
The Flexbox Approach: A Common Solution
When I first started using Tailwind, my go-to solution was Flexbox with items-center
. It's a natural choice - after all, Flexbox was designed for this kind of layout. Here's a common pattern you might see in feature lists or navigation menus:
<li class="flex items-center gap-x-3">
<svg class="size-5"><!-- icon path --></svg>
Seamless integrations with popular tools
</li>
This works perfectly when your text stays on a single line. The items-center
class does exactly what it says - it centers the items vertically within the flex container. Simple and clean!
But here's where it gets tricky. What happens when your text wraps to multiple lines? Let's see:
The problem becomes clear: items-center
centers the icon relative to the entire height of the wrapped text. Instead of staying aligned with the first line where it logically belongs, the icon awkwardly floats in the middle of the text block. This creates a disconnected, unpolished look that gets worse the more text you add.
This isn't just a minor visual quirk - it's a fundamental limitation of how Flexbox handles vertical alignment. When content wraps, the entire text block becomes the reference point for centering, not just the first line where we typically want our icons to align.
We could push the icon to the top of the line by using a margin-top, but this doesn't feel great, and if the text or icon size changes, then we also need to remember to update the margin.
The Margin Method: Quick but Fragile
Frustrated with the limitations of the Flexbox approach, many developers (myself included) have turned to the quick fix: margin adjustments.
<li class="flex gap-x-3">
<svg class="h-5 w-5 mt-[0.2rem]"><!-- icon path --></svg>
Feature description
</li>
At first glance, this seems great! It's simpler than the Flexbox solution - no extra div needed. Just add a carefully calculated margin-top, and voilà! The icon aligns perfectly with your text.
But there's a catch. Let's see what happens when we change text sizes:
That hardcoded margin value is making assumptions about your typography that simply don't scale. Change the text size from text-base
to text-lg
? Your alignment breaks. Switch the line height? Yep, breaks again.
I've spent more time than I'd like to admit tweaking margin values across different screen sizes and text styles. There has to be a better way, right?
Enter the Line Height (lh) Utility: The Elegant Solution
This is where the CSS class lh
comes in, Tailwind's V4 update allows us to use this new class,
and it's a game-changer. Instead of trying to manually calculate margins or wrapping icons in extra markup, we can now do this:
<li class="flex gap-x-3">
<svg class="h-[1lh] w-5"><!-- icon path --></svg>
Feature description
</li>
That's it. One simple class: h-[1lh]
. It tells the icon, "Hey, be exactly as tall as one line of the current text." No assumptions about text size, no manual calculations, no extra markup.
If we define a text-base/6
class, then the icon will be h-[1lh]
tall.
This means that the line height will always update to match the text size, you can try it out below,
Try to change the text-base/6
to text-base/9
and see how the icon height updates to match the new line height.
What makes this solution so elegant is that it automatically adapts to whatever context it's in. Change the text size? The icon adjusts. Modify the line height? The icon follows suit. It's like having an icon that automatically knows exactly how tall it should be to look perfect with your text.
See It in Action
But don't take my word for it - try it yourself! I've put together an interactive example that shows all three methods side by side. Play around with it, change some values, and see how each approach handles different scenarios:
Try these experiments with the code above:
- Change
text-base/6
totext-lg/7
in each example - Add more lines of text to see how alignment holds up
- Switch between different text sizes and line heights
You'll quickly see why the lh
utility is such a breakthrough. It's not just another way to align icons - it's the way we should have been doing it all along.
The Takeaway
While both the Flexbox and margin approaches have served us well over the years, the new lh
utility represents a significant step forward in how we handle icon alignment. It's more maintainable, more flexible, and just works the way we always wanted icon alignment to work.
Next time you're reaching for mt-[something]
or wrapping your icon in a flex container, remember there's a better way. The lh
utility is here to save us from the icon alignment headaches of the past!