Tailwind Best Practices
Tailwind is easy to start and easy to make messy. These habits keep large codebases readable and consistent.
Order Classes Consistently
Pick a stable order so scanning is predictable. A common one:
- Layout —
flex,grid,block - Positioning —
relative,absolute,z-10 - Spacing —
p-4,m-2,gap-4 - Size —
w-full,h-10,max-w-md - Typography —
text-lg,font-bold,leading-tight - Color —
bg-white,text-gray-900,border-gray-200 - Effects —
rounded-lg,shadow,opacity-50 - States —
hover:,focus:,dark: - Responsive —
sm:,md:,lg:
Prettier’s Tailwind plugin enforces this automatically.
Build a Small Design System
Decide a few tokens up front and stick to them:
- One spacing rhythm (
p-2,p-4,p-8). - A limited palette with semantic names.
- Two or three radius and shadow values.
Consistency beats novelty in every class list.
Components Over Repetition
If a block of classes appears three times, extract it. Repeated long strings are a maintenance trap.
Accessibility Is Not Optional
- Contrast — Test text against its background in both themes.
- Focus states — Always visible, never removed.
- Tap targets — At least 44×44px.
- Reduced motion — Respect
motion-reduce:.
<div class="transition-transform motion-reduce:transition-none">...</div>
Performance
- Unused utilities are purged at build time, so shipping is lean.
- Keep dynamic class names as full strings so they survive scanning.
- Do not fight the scanner with concatenation.
Readability
For very long lists, break across lines and group logically:
<button
class="
inline-flex items-center gap-2
rounded-lg bg-blue-600 px-4 py-2
font-medium text-white
hover:bg-blue-700 focus:ring-2 focus:ring-blue-400
"
>
Best Practices
- Enforce class order — Prettier plugin.
- Tokenize early — Fewer arbitrary values.
- Extract components — Reuse markup, not strings.
- Design accessible by default.
- Keep class lists readable — Group and wrap.
Common Mistakes
- Inconsistent spacing — Every value under the sun.
!importantas a strategy — Fix specificity instead.- Removing focus rings — Breaks keyboard users.
- Dynamic class strings — Silently dropped by the scanner.
- A thousand arbitrary values — You built a stylesheet, badly.