Episode 15 of 19

Hover Effects

Master Tailwind CSS hover, focus, active, and group-hover state variants. Build interactive UI effects with state-based styling.

State Variants in Tailwind

Tailwind lets you apply styles conditionally based on element state using variant prefixes. The most common are hover:, focus:, active:, and group-hover:.

Hover

<button class="bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 hover:shadow-lg">
  Hover me
</button>

<a href="#" class="text-gray-600 hover:text-indigo-600 hover:underline">
  Hover link
</a>

Focus

<input class="border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" placeholder="Focus me">

<button class="bg-indigo-600 text-white py-2 px-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
  Focus ring
</button>

Active

<button class="bg-indigo-600 text-white py-2 px-4 rounded-lg hover:bg-indigo-700 active:bg-indigo-800 active:scale-95 transform transition">
  Press me
</button>

Group Hover

Apply hover styles to a child when the parent is hovered. Add group to the parent and group-hover: to children:

<div class="group bg-white rounded-xl shadow-md p-6 hover:shadow-xl transition-shadow cursor-pointer">
  <h3 class="font-bold text-gray-900 group-hover:text-indigo-600 transition-colors">
    Card Title
  </h3>
  <p class="text-gray-500 mt-2">Hover the card to see the title change color.</p>
  <span class="mt-4 inline-block text-indigo-600 font-semibold opacity-0 group-hover:opacity-100 transition-opacity">
    Read more →
  </span>
</div>

First & Last Child

<ul class="divide-y divide-gray-200">
  <li class="py-3 first:pt-0 last:pb-0">Item A</li>
  <li class="py-3 first:pt-0 last:pb-0">Item B</li>
  <li class="py-3 first:pt-0 last:pb-0">Item C</li>
</ul>

Odd & Even

<table class="w-full">
  <tbody>
    <tr class="odd:bg-gray-50 even:bg-white"><td class="p-3">Row 1</td></tr>
    <tr class="odd:bg-gray-50 even:bg-white"><td class="p-3">Row 2</td></tr>
    <tr class="odd:bg-gray-50 even:bg-white"><td class="p-3">Row 3</td></tr>
    <tr class="odd:bg-gray-50 even:bg-white"><td class="p-3">Row 4</td></tr>
  </tbody>
</table>

Combining States

You can stack variants:

<!-- Dark mode + hover -->
<button class="bg-gray-200 hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600">
  Combined states
</button>

<!-- Responsive + hover -->
<div class="text-sm md:text-base md:hover:text-indigo-600">
  Responsive hover
</div>

Practical Example — Interactive Card

<div class="group bg-white rounded-2xl shadow-md hover:shadow-2xl p-6 transition-all duration-300 cursor-pointer max-w-sm">
  <div class="overflow-hidden rounded-xl mb-4">
    <img src="https://picsum.photos/400/200" alt="" class="w-full h-44 object-cover group-hover:scale-110 transition-transform duration-500">
  </div>
  <span class="bg-indigo-100 text-indigo-800 text-xs font-semibold px-2.5 py-0.5 rounded-full">Featured</span>
  <h3 class="mt-3 text-lg font-bold text-gray-900 group-hover:text-indigo-600 transition-colors">Interactive Design</h3>
  <p class="mt-2 text-sm text-gray-500">Hover effects make your UI feel alive and responsive.</p>
</div>

All State Variants

PrefixApplies When
hover:Mouse cursor is over the element
focus:Element has keyboard focus
focus-within:Any child has focus
active:Element is being pressed
visited:Link has been visited
disabled:Element is disabled
checked:Checkbox/radio is checked
first:First child element
last:Last child element
odd:Odd-numbered child
even:Even-numbered child
group-hover:Parent with group class is hovered

Recap

  • State variants (hover:, focus:, active:) apply styles conditionally.
  • group + group-hover: lets parent hover affect children.
  • Combine states with responsive prefixes: md:hover:text-indigo-600.
  • first:, last:, odd:, even: target list and table patterns.

Next up: building a responsive navigation bar — part 1!

Web DevelopmentTailwind CSSCSSHover EffectsInteractivity