Invent Your Own Variant Prefixes
@variant & @custom-variant
Create reusable variants such as a class-based dark mode or an app-specific state with @custom-variant, and apply them in CSS with @variant.
What you'll learn
- Define a class-based dark variant with @custom-variant
- Create app-specific state variants
- Use @variant inside custom CSS rules
Variants are the prefixes like hover: and md:. @custom-variant lets you define new ones from any selector, and @variant lets you use a variant inside hand-written CSS.
Class-Based Dark Mode
By default dark: follows the OS setting. To make it toggle from a .dark class instead, redefine the variant:
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *)); Now dark:bg-gray-900 applies whenever an ancestor carries the dark class, which a theme toggle can add or remove. The :where() wrapper keeps specificity at zero so utilities still override cleanly.
App-Specific Variants
Any selector you can write becomes a variant. A variant that activates when the sidebar is open:
@custom-variant sidebar-open (body:has(.sidebar-open) &);
@custom-variant aria-current (&[aria-current="page"]); <main class="ml-0 sidebar-open:ml-64 transition-[margin]">
Shifts when the sidebar opens
</main> @variant Inside CSS
When you write a custom component class, @variant applies a variant to a block of declarations:
.btn {
background: var(--color-blue-600);
color: white;
@variant dark {
background: black;
}
@variant hover {
background: var(--color-blue-700);
}
} This keeps variant logic consistent between utilities and your own CSS, with no media-query or selector duplication to maintain by hand.
Arbitrary Values & Properties →