TechLead
Lección 5 de 9
5 min de lectura
Tailwind CSS

Hover, Focus y Variantes de Estado

Estiliza estados interactivos como hover, focus, active y disabled usando los modificadores de variantes de estado de Tailwind.

Variantes de Estado en Tailwind

Tailwind proporciona modificadores para estilizar elementos según su estado. Estos modificadores se pueden combinar con cualquier clase utilitaria.

Estado Hover

<!-- Hover básico -->
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
  Hover me
</button>

<!-- Hover con múltiples cambios -->
<div class="bg-white hover:bg-gray-50 hover:shadow-lg transition-all p-4 rounded">
  Hover for effects
</div>

<!-- Color de texto en hover -->
<a href="#" class="text-gray-600 hover:text-blue-600">
  Hover link
</a>

Estado Focus

<!-- Focus ring -->
<input
  type="text"
  class="border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 rounded px-4 py-2 outline-none"
  placeholder="Focus me"
>

<!-- Focus visible (solo teclado) -->
<button class="px-4 py-2 bg-blue-500 text-white rounded focus-visible:ring-2 focus-visible:ring-blue-300 focus-visible:ring-offset-2">
  Keyboard focus only
</button>

<!-- Focus within (hijo con focus) -->
<div class="p-4 border focus-within:border-blue-500 focus-within:ring-2 focus-within:ring-blue-200 rounded">
  <input type="text" class="outline-none" placeholder="Focus changes parent">
</div>

Estado Active

<button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700 active:scale-95 transition-all text-white px-4 py-2 rounded">
  Click and hold
</button>

Estado Disabled

<button
  disabled
  class="bg-blue-500 text-white px-4 py-2 rounded disabled:bg-gray-300 disabled:cursor-not-allowed disabled:opacity-50"
>
  Disabled Button
</button>

<input
  disabled
  class="border rounded px-4 py-2 disabled:bg-gray-100 disabled:text-gray-400"
  value="Disabled input"
>

Group Hover

Estiliza elementos hijos según el hover del contenedor padre:

<div class="group p-4 bg-white hover:bg-blue-500 rounded transition-colors">
  <h3 class="font-bold text-gray-900 group-hover:text-white">
    Card Title
  </h3>
  <p class="text-gray-600 group-hover:text-blue-100">
    Card description changes on parent hover
  </p>
  <span class="text-blue-500 group-hover:text-white group-hover:translate-x-2 inline-block transition-all">
    Learn more →
  </span>
</div>

Modificador Peer

Estiliza un elemento según el estado de un hermano:

<div>
  <input type="checkbox" id="toggle" class="peer sr-only">
  <label for="toggle" class="cursor-pointer">Toggle</label>
  <div class="hidden peer-checked:block mt-2 p-4 bg-green-100 rounded">
    This appears when checkbox is checked
  </div>
</div>

<!-- Estilos para validación de formularios -->
<div>
  <input
    type="email"
    class="peer border rounded px-4 py-2 invalid:border-red-500"
    placeholder="Enter email"
    required
  >
  <p class="hidden peer-invalid:block text-red-500 text-sm mt-1">
    Please enter a valid email
  </p>
</div>

First, Last, Odd, Even

<ul class="divide-y">
  <li class="py-2 first:pt-0 last:pb-0">Item 1</li>
  <li class="py-2 first:pt-0 last:pb-0">Item 2</li>
  <li class="py-2 first:pt-0 last:pb-0">Item 3</li>
</ul>

<!-- Zebra striping -->
<table>
  <tbody>
    <tr class="odd:bg-gray-50 even:bg-white"><td>Row 1</td></tr>
    <tr class="odd:bg-gray-50 even:bg-white"><td>Row 2</td></tr>
    <tr class="odd:bg-gray-50 even:bg-white"><td>Row 3</td></tr>
  </tbody>
</table>

Estados de Formularios

<!-- Campo requerido -->
<input
  type="text"
  required
  class="border rounded px-4 py-2 required:border-red-500"
>

<!-- Válido/Inválido -->
<input
  type="email"
  class="border rounded px-4 py-2 valid:border-green-500 invalid:border-red-500"
>

<!-- Placeholder visible -->
<input
  type="text"
  placeholder="Enter name"
  class="border rounded px-4 py-2 placeholder-shown:border-gray-300"
>

<!-- Solo lectura -->
<input
  readonly
  value="Read only"
  class="border rounded px-4 py-2 read-only:bg-gray-100"
>

Combinando Estados

<!-- Responsive + hover -->
<button class="bg-blue-500 md:hover:bg-blue-600 lg:hover:bg-blue-700">
  Responsive hover
</button>

<!-- Modo oscuro + hover -->
<button class="bg-white hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700">
  Dark mode aware
</button>

<!-- Group + focus -->
<div class="group">
  <input class="peer" type="text">
  <span class="group-hover:text-blue-500 peer-focus:text-green-500">
    Label
  </span>
</div>

Ejemplo de Botón Interactivo

<button class="
  px-6 py-3
  bg-gradient-to-r from-blue-500 to-purple-500
  hover:from-blue-600 hover:to-purple-600
  active:from-blue-700 active:to-purple-700
  focus:ring-4 focus:ring-blue-300
  disabled:from-gray-400 disabled:to-gray-400 disabled:cursor-not-allowed
  text-white font-semibold rounded-lg
  transform hover:scale-105 active:scale-95
  transition-all duration-200
  shadow-lg hover:shadow-xl
">
  Interactive Button
</button>

Continuar Aprendiendo