Tailwind moves configuration from JavaScript to CSS using the @theme directive and CSS variables.
Defining Custom Colors
Add colors in your CSS file using @theme:
@import 'tailwindcss';
@theme {
--color-brand: #5b21b6;
--color-neon-pink: oklch(71.7% 0.25 360);
--color-neon-lime: oklch(91.5% 0.258 129);
}This generates utilities like bg-brand, text-neon-pink, etc.
Overriding Default Colors
Replace specific colors:
@theme {
--color-blue-500: #1e40af; /* Override default blue-500 */
}Clear entire color groups:
@theme {
--color-gray-*: initial; /* Remove all default grays */
--color-gray-50: #f8fafc;
--color-gray-100: #f1f5f9;
/* Define your custom grays */
}Start from scratch:
@import 'tailwindcss/preflight';
@import 'tailwindcss/utilities';
@theme {
--color-*: initial; /* Remove ALL defaults */
/* Define your entire palette */
}Using Colors as CSS Variables
Theme colors are exposed as CSS variables:
In Custom CSS
.custom-element {
background: var(--color-brand);
border-color: var(--color-neon-pink);
}In Arbitrary Values
<!-- Long form -->
<div class="bg-[var(--color-neon-pink)]">...</div>
<!-- Shorthand (v4) -->
<div class="text-(--color-brand)">...</div>Opacity Modifiers
Works with all color definitions:
<div class="bg-brand/50">50% opacity</div>
<div class="text-neon-pink/75">75% opacity</div>
<div class="border-[var(--color-custom)]/20">20% opacity</div>Important Tailwind 4 Changes
Border Color Default
<!-- v3: defaulted to gray-200 -->
<div class="border">...</div>
<!--Tailwind 4: defaults to currentColor -->
<div class="border border-gray-200">Explicit color needed</div>Ring Color Default
<!-- v3: 3px blue ring -->
<div class="ring">...</div>
<!--Tailwind 4: 1px currentColor -->
<div class="ring-3 ring-blue-500">Explicit width and color</div>Dynamic Theming
CSS variables enable runtime theme switching:
@theme {
--color-surface: white;
--color-text: black;
}
[data-theme='dark'] {
--color-surface: #1a1a1a;
--color-text: white;
}<body data-theme="dark">
<div class="bg-surface text-text">Automatically themed</div>
</body>Best Practices
- Use semantic names for brand colors:
--color-primary,--color-accent - Group related colors:
--color-gray-*,--color-brand-* - Leverage OKLCH for consistent palettes
- Document your colors with comments in
@theme - Test opacity modifiers with your custom colors