Topics in this subject
Tailwind 2 min read Updated 12 Aug 2026

Pseudo-classes and State

Applying styles on hover, focus, active states, and advanced group/peer interactions.

🧑‍🏫 Sabse pehle — simple mein samjho#

Vanilla CSS mein hover effect lagane ke liye tumhe alag se .btn:hover { ... } likhna padta hai. Tailwind mein ye sab ek hi line mein ho jata hai. Bas class ke aage hover: laga do. Jaise bg-blue-500 hover:bg-blue-600. Same goes for buttons jo click hone par thode dabbe hue (active) dikhne chahiye ya inputs jo click hone par highlight (focus) hone chahiye.

The Basic States#

To apply a style only under a specific condition, prepend the state name followed by a colon :.

  • Hover (hover:): Applies when the mouse pointer is over the element. hover:bg-blue-600
  • Focus (focus:): Applies when the element is clicked or tabbed into (inputs, buttons). focus:ring-2 focus:ring-blue-500
  • Active (active:): Applies exactly while the element is being clicked/pressed down. active:scale-95 (Creates a nice click-in animation)
  • Disabled (disabled:): Applies when a button or input has the disabled HTML attribute. disabled:opacity-50 disabled:cursor-not-allowed
<!-- Hover, Focus, Active, and Disabled States -->
<div class="flex gap-4 p-8 bg-gray-50 rounded-xl justify-center items-center">
  <button class="bg-blue-500 hover:bg-blue-600 active:scale-95 focus:ring-4 focus:ring-blue-300 text-white font-semibold py-2.5 px-6 rounded-lg transition-all outline-none">
    Submit
  </button>
  <button disabled class="bg-gray-300 text-gray-500 font-semibold py-2.5 px-6 rounded-lg cursor-not-allowed opacity-75">
    Disabled
  </button>
</div>

Advanced State Management (Group and Peer)#

Sometimes you want an element to change its style based on the state of a different element.

1. The group modifier (Parent -> Child)#

If you hover over a card (parent), you want a small icon inside it (child) to change color.

  • Add the group class to the parent.
  • Add group-hover:{style} to the child.
<!-- Group Hover Example (Hover over the card to see the icon and text change) -->
<div class="group max-w-sm mx-auto border border-gray-200 bg-white p-6 rounded-2xl hover:bg-indigo-50 hover:border-indigo-200 transition-colors cursor-pointer shadow-sm">
  <div class="flex items-center gap-4">
    <div class="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center group-hover:bg-indigo-500 transition-colors">
      <svg class="w-6 h-6 text-gray-500 group-hover:text-white transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
    </div>
    <div>
      <h3 class="font-bold text-gray-900 group-hover:text-indigo-900 transition-colors m-0">Performance Analytics</h3>
      <!-- The text slides in and fades in on parent hover -->
      <p class="text-sm text-indigo-600 opacity-0 -translate-x-2 group-hover:opacity-100 group-hover:translate-x-0 transition-all m-0 mt-1">View detailed report &rarr;</p>
    </div>
  </div>
</div>

2. The peer modifier (Sibling -> Sibling)#

If you focus on an input field, you want the label directly next to it to change color. (This relies on the CSS general sibling combinator).

  • Add the peer class to the input (it must come first in the HTML).
  • Add peer-focus:{style} to the sibling label.
<!-- Peer Example (Click the input field to see the label and border react) -->
<form class="max-w-sm mx-auto p-6 bg-white rounded-xl shadow-md border border-gray-100">
  <div class="relative">
    <!-- The input acts as the trigger (peer) -->
    <input type="email" id="email" required placeholder=" " class="peer w-full border border-gray-300 px-4 py-3 rounded-lg outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors bg-transparent pt-6 pb-2" />
    
    <!-- Floating Label reacts to peer-focus and peer-placeholder-shown -->
    <label for="email" class="absolute left-4 top-4 text-gray-500 transition-all peer-focus:top-2 peer-focus:text-xs peer-focus:text-indigo-600 peer-focus:font-semibold peer-placeholder-shown:top-4 peer-placeholder-shown:text-base pointer-events-none">Email address</label>
  </div>
  
  <!-- Validation message reacts to peer-invalid (when touched/submitted) -->
  <p class="hidden peer-invalid:block text-rose-500 text-xs mt-2 font-medium">Please enter a valid email address.</p>
</form>