States & Variants
Variants let a utility apply only in a certain state. Prefix a class with hover:, focus:, dark:, and more.
Hover, Focus, Active
<button
class="bg-blue-600 text-white hover:bg-blue-700 active:bg-blue-800 focus:ring-2 focus:ring-blue-400 focus:outline-none"
>
Click me
</button>
The base class applies always; the variant applies only in that state.
Common State Variants
| Variant | When it applies |
|---|---|
hover: |
Pointer over the element |
focus: |
Element has keyboard/input focus |
active: |
Being pressed |
disabled: |
Disabled form control |
visited: |
Visited link |
checked: |
Checked checkbox/radio |
Dark Mode
<div class="bg-white text-gray-900 dark:bg-gray-900 dark:text-gray-100">
Adapts to dark mode
</div>
Configure how dark mode is detected (system vs a class) in your CSS. The dark: prefix then works everywhere.
Responsive Variants
Breakpoint prefixes are variants too:
<div class="text-sm md:text-base lg:text-lg">Scales up</div>
md: and up. Mobile-first: write the small screen first, add prefixes for larger.
Group: Style from a Parent
Mark a parent group, then react to its state from a child:
<a class="group block rounded-lg p-4 hover:bg-gray-100">
<h3 class="font-semibold group-hover:text-blue-600">Title</h3>
<p class="text-gray-500 group-hover:text-gray-700">Body</p>
</a>
Hovering the card changes the title and body.
Peer: Style from a Sibling
peer works the same way for siblings, common in forms:
<input type="email" class="peer border p-2" />
<p class="invisible text-sm text-red-500 peer-invalid:visible">
Please enter a valid email
</p>
Combining Variants
Stack prefixes for precise targeting:
<button class="hover:focus:bg-blue-800 md:dark:hover:bg-blue-500">
Combined
</button>
Order reads left to right: breakpoint, then state.
Best Practices
- Design focus states — Never remove them without a replacement.
- Use
groupfor cards — Cleaner than per-child hover styles. - Keep variants readable — Do not stack more than two or three.
- Mobile-first — Base styles for small screens, prefixes for larger.
Common Mistakes
- Using
hover:for touch — Touch devices have no hover. - Removing focus outlines — Breaks keyboard accessibility.
- Forgetting
groupon the parent —group-hover:does nothing without it. - Wrong breakpoint order — Prefixes apply at that width and up.