Organising long class lists
An element with responsive styles, states and dark mode easily collects twenty classes. Tailwind copes fine, but such an attribute is hard for a human to read. A consistent class order, automatic sorting and careful conditional classes help.
A consistent order
Agree to write classes in one sequence: layout first, then sizing and spacing, decoration, text, and variants at the end:
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<button class="flex items-center gap-2 rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-500 focus-visible:ring-2 md:px-6">
Add to cart
</button>Reading from left to right you see how the content is arranged, what shape the button has, what the text is like and how it changes. Keeping the order by hand is tedious — Prettier does it for you.
The Prettier plugin
Prettier is a popular code formatter. The official prettier-plugin-tailwindcss plugin sorts classes in the order they appear in the generated CSS. Install both packages in the project:
npm install -D prettier prettier-plugin-tailwindcssCreate a .prettierrc file in the project root and add the plugin. For Tailwind 4, give the path to the main CSS file — that is where the plugin learns about your theme and custom utilities:
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindStylesheet": "./src/style.css"
}Format the files with:
npx prettier --write .Classes in all files line up in the same order. Prettier is usually set to format on save in the editor — then you never think about the order at all.
Line breaks
A very long attribute can be split into lines by meaning — HTML allows it:
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<div class="
grid grid-cols-1 gap-4
sm:grid-cols-2
lg:grid-cols-4
">
<div class="rounded bg-indigo-100 p-4">1</div>
<div class="rounded bg-indigo-100 p-4">2</div>
</div>Conditional classes
In components, classes often depend on data. Write each branch in full instead of gluing a name from pieces:
// src/components/StockBadge.jsx
export default function StockBadge({ inStock }) {
const color = inStock ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-500';
return <span className={`rounded px-2 py-1 text-sm ${color}`}>{inStock ? 'In stock' : 'Out of stock'}</span>;
}Both sets of classes are written in full, so the build finds them. For complex cases there are small libraries clsx and tailwind-merge: the first builds a class string from conditions, the second removes conflicting classes.
Common mistake
Putting two conflicting classes on one element and hoping the last one in the attribute wins:
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<button class="bg-indigo-600 px-4 py-2 text-white bg-red-600">Delete</button>Which background you get is decided by the rule order in the CSS, not in the attribute. Remove the extra class instead of adding a second one on top. The Tailwind CSS IntelliSense extension underlines such conflicts right in the editor.