What Tailwind variant prefixes do
Tailwind utility classes are unconditional by default — bg-blue-500 always
applies. Variant prefixes make a utility conditional: hover:bg-blue-500 only
paints on hover, md:bg-blue-500 only above the medium breakpoint, and
dark:bg-blue-500 only in dark mode. This reference lists the common variants,
the CSS selector or at-rule each compiles to, and how to stack them.
How it works
A variant is just a prefix plus a colon. At build time Tailwind’s JIT engine reads the class name, looks up the variant, and wraps the utility’s declaration in the matching selector or media query:
/* hover:bg-blue-500 */
.hover\:bg-blue-500:hover { background-color: #3b82f6 }
/* md:flex */
@media (min-width: 768px) { .md\:flex { display: flex } }
/* dark:text-white (media strategy) */
@media (prefers-color-scheme: dark) { .dark\:text-white { color: #fff } }
Stacked variants combine their conditions. md:dark:hover:underline only
underlines when the viewport is >= 768px, the theme is dark, and the element
is hovered — all three must hold.
Tips and notes
- Write variants outer-to-inner for readability: responsive, then theme, then
state, e.g.
lg:dark:hover:. group-*needs agroupclass on an ancestor;peer-*needs apeerclass on an earlier sibling.- Attribute variants like
aria-expanded:anddata-[state=open]:target real DOM attributes, keeping JS-driven state in sync with styling. - Use arbitrary variants
[&_selector]:for one-off cases instead of bloating your config.