Tips & Tricks for Writing Better Tailwind CSS
Do you write in Tailwind CSS? Here are some tips and tricks I use to optimize my code's look and performance.
Want to add more tips? Create a PR on GitHub.
Delegate Classes to Parent Element
Incorrect
<ul>
<li class="whitespace-nowrap text-sm font-medium">First</li>
<li class="whitespace-nowrap text-sm font-medium">Second</li>
<li class="whitespace-nowrap text-sm font-medium">Third</li>
</ul>
Correct
<ul class="text-sm font-medium">
<li class="whitespace-nowrap">First</li>
<li class="whitespace-nowrap">Second</li>
<li class="whitespace-nowrap">Third</li>
</ul>
Remove Flex Classes on Mobile
Incorrect
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between">
<div>Hello</div>
<div>World</div>
</div>
Correct
<div class="sm:flex sm:items-center sm:justify-between">
<div>Hello</div>
<div>World</div>
</div>
Evenly Space Content with Flow Root
Incorrect
<ul class="space-y-8 divide-y">
<li>First</li>
<li class="pt-8">Second</li>
<li class="pt-8">Third</li>
</ul>
Correct
<div class="flow-root">
<ul class="-my-8 divide-y">
<li class="py-8">First</li>
<li class="py-8">Second</li>
<li class="py-8">Third</li>
</ul>
</div>
But this is more code
True, however...
- Which one will make more sense in a few months time?
- How would the first example work with dynamic content?
Avoid Margin Bottom for Spacing Content
Incorrect
<div>
<div class="mb-4">Hello</div>
<div>World</div>
</div>
Correct
<div>
<div>Hello</div>
<div class="mt-4">World</div>
</div>
What is the benefit, they do the same thing?
Sure, but what if the content is dynamic and there's no second element? You'll end up with extra space below the first element.
Remove Duplicate Spacing Classes with Parent Classes
Incorrect
<ul>
<li>First</li>
<li class="mt-8">Second</li>
<li class="mt-8">Third</li>
</ul>
Correct
<ul class="space-y-8">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Use the Accurate Transition Class
Incorrect
<button class="bg-red-500 transition-all hover:bg-red-600">Click</button>
Correct
<button class="bg-red-500 transition-colors hover:bg-red-600">Click</button>
But the class name is longer?
Can't argue with that, but do you need transition-all
? Probably not.
If you want to save on class name length then use transition
it will cover
99% of the transition effects you need.
Use Color Opacity Classes
Incorrect
<button class="relative">
<span class="absolute inset-0 bg-red-500 opacity-50"></span>
Click
</button>
Correct
<button class="bg-red-500 bg-opacity-50">Click</button>
<!-- With JIT -->
<button class="bg-red-500/50">Click</button>
Split CSS Class Names onto Multiple Lines in CSS Files
Incorrect
.button {
@apply inline-flex items-center rounded border px-5 py-3 text-sm transition hover:scale-105;
}
Correct
.button {
@apply inline-flex items-center; // Layout
@apply px-5 py-3 text-sm; // Spacing/Sizing
@apply rounded border; // Style
@apply transition; // Transition
@apply hover:scale-105; // Interaction
}
How is this better? It's more code...
Correct, but it's easier to read and it all gets compiled down.
Avoid Creating Components in CSS Files
Only applies if you are using a templating language that allows for components, such as Blade, React, Liquid OR Vue.
Incorrect
<div class="card">
<div class="card-title">Title</div>
<div class="card-body">Title</div>
<div class="card-footer">
<div class="card-timestamp">15/05/2025</div>
<div class="card-actions">
<button>Edit</button>
<button>Delete</button>
</div>
</div>
</div>
And for the CSS...
.card {
@apply rounded p-4;
}
.card-title {
@apply text-lg;
}
.card-body {
@apply mt-1;
}
.card-footer {
@apply flex items-center justify-between;
}
.card-timestamp {
@apply text-sm;
}
.card-actions {
@apply flex gap-4;
}
Correct
<div class="rounded p-4">
<div class="text-lg">Title</div>
<div class="mt-1">Title</div>
<div class="flex items-center justify-between">
<div class="text-sm">15/05/2025</div>
<div class="flex gap-4">
<button>Edit</button>
<button>Delete</button>
</div>
</div>
</div>
Use Max Width Classes When Restricting Width
Incorrect
<div class="w-auto sm:w-64">
<div>Hello World</div>
</div>
Correct
<div class="max-w-sm">
<div>Hello World</div>
</div>
What's the benefit?
There are several:
- They are responsive by default
- They better describe the layout
Group Prefixed Class Names
Incorrect
<div class="\\mt-4 lg:text-3xl\\ text-lg sm:mt-0 sm:text-xl">Hello World</div>
Excuse the \\...\\
it's to stop Prettier from formatting.
Correct
<div class="mt-4 text-lg sm:mt-0 sm:text-xl lg:text-3xl">Hello World</div>
You can use something like Tailwind CSS Prettier to do this for you.
Be Specific with Breakpoint Classes
Incorrect
<div class="items-center justify-between sm:flex">
<div>Hello</div>
<div>World</div>
</div>
Correct
<div class="sm:flex sm:items-center sm:justify-between">
<div>Hello</div>
<div>World</div>
</div>
What's the issue here?
You are loading extra CSS on mobile that isn't being used. While it may not seem drastic in this example, imagine if the entire frontend was written like the first example. That's a lot of extra CSS being loaded on mobile.
Use Tailwind CSS Prettier and Tailwind CSS Intellisense
Tailwind CSS Prettier
Tailwind CSS Prettier GitHub Repo
- Sort Tailwind CSS class names
- Remove duplicate class names
- Move custom class names to end of class name list
Tailwind CSS Intellisense
Tailwind CSS Intellisense GitHub Repo
- Autocomplete Tailwind CSS class names (includes classes added in the Tailwind CSS config)
- Highlights errors with Tailwind CSS class names
- Displays the CSS generated with each Tailwind CSS class