Customizing Tailwind
Tailwind’s defaults are a great starting point, but every brand has its own colors, fonts, and spacing. In v4 you customize with CSS.
The @theme Block
Define design tokens in your CSS entry:
@import "tailwindcss";
@theme {
--color-brand: oklch(0.65 0.2 150);
--font-display: "Satoshi", sans-serif;
--spacing: 0.25rem;
--radius-card: 0.75rem;
}
These become utilities automatically: bg-brand, text-brand, font-display, rounded-card.
Adding Custom Colors
@theme {
--color-brand-50: oklch(0.97 0.02 150);
--color-brand-500: oklch(0.65 0.2 150);
--color-brand-900: oklch(0.3 0.1 150);
}
Now the full shade scale is available: bg-brand-500, border-brand-900, and so on.
Custom Fonts
@theme {
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, monospace;
}
font-sans and font-mono use your fonts everywhere.
Arbitrary Values
For one-off values, use square brackets:
<div class="w-[137px] top-[calc(100%-2rem)] bg-[#1a2b3c]">
Arbitrary
</div>
Handy for a quick fix — but if you use the same value repeatedly, promote it to a token.
Custom Utilities
Define your own utility with @utility:
@utility content-auto {
content-visibility: auto;
}
<article class="content-auto">Long page</article>
Best Practices
- Tokenize repeated values — One-off
[13px]becomes a theme token. - Name by role —
--color-danger, not--color-red. - Keep the scale coherent — Add shades that fit the existing rhythm.
- Use arbitrary values sparingly — They bypass the design system.
Common Mistakes
- Arbitrary values everywhere — The system stops being a system.
- Overriding defaults carelessly — You may break utilities you rely on.
- Too many brand shades — Five is usually enough.
- Forgetting dark variants — Custom tokens need dark values too.