State Variants

hover, focus, active — Styled Inline

State Variants

Prefix utilities with interaction-state variants so styles apply only in that state.

4 min read Level 2/5 #tailwind#variants#states
What you'll learn
  • Use hover, focus, active, and disabled variants
  • Stack variants together
  • Use focus-visible for keyboard accessibility

Interaction states are variants too. Instead of writing :hover rules in a stylesheet, you prefix the utility that should change.

The Common States

<button class="bg-blue-600 text-white px-4 py-2 rounded-md
               hover:bg-blue-700
               active:scale-95
               disabled:opacity-50 disabled:pointer-events-none">
  Save
</button>

Each prefixed utility activates only in its state: a darker background on hover, a subtle press on active, a dimmed and inert look when disabled.

Stacking Variants

Variants compose, and they read left to right. md:hover:underline means “from medium screens up, when hovered, underline”:

<a class="text-blue-600 md:hover:underline">Hover me on desktop</a>

There is no limit to stacking — dark:md:hover:bg-gray-700 is perfectly valid.

Focus and Keyboard Accessibility

focus: applies on any focus, including mouse clicks, which makes focus rings appear when many users do not expect them. Prefer focus-visible:, which the browser only triggers for keyboard navigation:

<button class="rounded-md px-4 py-2
               focus:outline-none
               focus-visible:ring-2 focus-visible:ring-blue-500">
  Accessible button
</button>

One firm rule: if you use focus:outline-none, you must pair it with a visible alternative like focus-visible:ring-2. Removing the outline with no replacement makes a control invisible to keyboard users and is an accessibility failure.

Dark Mode →