Tailwind CSS Best Practices
Tailwind's utility-first approach can be very handy, but getting the most out of it requires adopting a few important habits. Incorporating the following best practices will help you write cleaner, more maintainable code and avoid the most common pitfalls.
1. Don't Abstract Too Early
One of the most common mistakes Tailwind newcomers make is reaching for @apply or component classes too early, essentially recreating the problems that Tailwind is designed to solve. The recommended workflow is:
- Start with utilities directly in your HTML. Don't worry about repeated class strings at first.
- Wait until a pattern is clearly repeated across multiple templates or components before extracting it.
- Extract into reusable components using your framework's component system (React, Vue, Blade, etc.), not
@apply.
Abstraction via @apply is best reserved for situations where a component system is not available (for example, styling Markdown-generated HTML or a third-party widget). When you do use it, keep the class names semantic:
Avoid using @apply just to shorten repeated class lists in your own templates.
2. Use Your Design Tokens Consistently
Tailwind's power comes from its design constraints. The moment you start mixing arbitrary values (w-[247px], text-[13.5px]) throughout your codebase, you lose the consistency benefits. Follow these guidelines:
- Use scale values first. Try
w-64before you usew-[256px]. - Define custom tokens in
@theme. If you need a brand color or spacing value that doesn't exist in the default theme, add it to your theme configuration so it becomes a proper named token (e.g.,bg-brandinstead ofbg-[##123abc]). - Limit arbitrary values to true one-offs. An arbitrary value is fine for a single pixel-perfect edge case, but it's not so good if you're writing the same one in five places.
3. Build Mobile-First
Tailwind's responsive prefixes (sm:, md:, lg:, xl:, 2xl:) apply styles at a minimum width. This means the unprefixed utilities always apply to the smallest screen first, and overrides cascade upward.
Building mobile-first means:
- Write your base styles for a single column, small-screen layout first.
- Add responsive prefixes to progressively enhance the layout for wider screens.
- Avoid using
max-breakpoints likemax-md:unless you have a specific reason, as they lead to confusing specificity logic.
4. Never Forget Accessibility
Utility-first CSS makes it easy to focus purely on visual output and forget about accessibility. Here are the most important things to keep in mind:
- Focus states: Always provide visible focus rings. Use
focus:ring-2 focus:ring-blue-500on interactive elements and never justoutline-nonewithout afocus:replacement. - Color contrast: Tailwind's color palette is well-thought-out, but always verify that your chosen text/background combinations meet WCAG contrast requirements. The 600-900 range for text on white backgrounds is generally safe.
- Motion: Use
motion-reduce:transition-noneandmotion-reduce:animate-noneto respect users who have enabled the "Reduce Motion" system preference. - Screen reader utilities: Use
sr-onlyto provide screen-reader accessible labels for icon-only buttons without visually showing the text, andnot-sr-onlyto restore its visibility when needed.
5. Optimise for Performance
Tailwind generates your CSS at build time by scanning your source files for class names. The generated stylesheet only includes the classes you actually use, so the output is minimal by default. However, there are a few things to keep in mind:
- Don't construct class names dynamically. Tailwind's scanner looks for complete class name strings. If you do something like
"text-" + colorin JavaScript, the scanner won't find it, and the class won't be included in the build. Always use complete class names:color === 'red' ? 'text-red-500' : 'text-blue-500'. - Use
@sourceto expand the scan (Tailwind v4+). If you have files outside the default scan paths (like a.phpadmin panel or legacy templates), tell Tailwind to include them with the@sourcedirective in your CSS. - The CDN build is for development only. Never use the Tailwind CDN script in production. Use the CLI or a build tool integration to generate a compiled, minimal stylesheet.
- Avoid large numbers of arbitrary values. Each unique arbitrary value generates a unique CSS rule. A handful is fine, but dozens of unique pixel values bloat the output.
6. Organise Your Class Lists
Long class strings on HTML elements can become difficult to read. A few conventions help:
- Follow a consistent ordering: layout → box model → typography → colors → effects → interactive states. The Prettier Tailwind plugin can enforce this automatically.
- Group variants together: Keep all
hover:classes together, allfocus:classes together, etc. - Break long class attributes over multiple lines in templates where your editor supports it. Readability trumps density.
In the final page, we'll wrap up the tutorial with a summary and point you towards further resources.