Saltar al contenido principal
Logo de JSCamp

Pseudo-clases en CSS

Aprende a usar pseudo-clases en CSS para estilizar elementos según su estado

midudev

Más clases y directos en YouTube

Suscribirse

Pseudo-clases en CSS

Las pseudo-clases son selectores especiales en CSS que nos permiten aplicar estilos a elementos según su estado o posición. Son fundamentales para crear interfaces interactivas y accesibles.

¿Qué es una pseudo-clase?

Una pseudo-clase se escribe con dos puntos : seguido del nombre de la pseudo-clase:

selector:pseudo-clase {  /* estilos */}

Las pseudo-clases más comunes relacionadas con la interacción del usuario son:

  • :hover - cuando el usuario pasa el ratón sobre el elemento
  • :focus - cuando el elemento tiene el foco (seleccionado)
  • :active - cuando el elemento está siendo activado/clicado
  • :disabled - cuando el elemento está deshabilitado

:hover - Al pasar el ratón

La pseudo-clase :hover se activa cuando el usuario pasa el cursor del ratón sobre un elemento.

¿Por qué es importante?

  • Feedback visual: El usuario sabe que el elemento es interactivo
  • Mejora la UX: Indica claramente los elementos clicables
  • Guía al usuario: Muestra qué elementos responden a la interacción

:focus - Cuando tiene el foco

La pseudo-clase :focus se activa cuando un elemento recibe el foco, generalmente al hacer clic en él o al navegar con el teclado (usando la tecla Tab).

¿Por qué es importante?

  • Accesibilidad: Los usuarios que navegan con teclado necesitan ver qué elemento está seleccionado
  • Formularios: Indica qué campo está activo para escribir
  • Navegación por teclado: Esencial para usuarios con discapacidades motoras

:focus en botones

Importante: Nunca elimines completamente los estilos de focus sin proporcionar una alternativa visual. Los usuarios que navegan con teclado los necesitan.

:active - Al hacer clic

La pseudo-clase :active se activa en el momento exacto en que el usuario está presionando un elemento (mientras mantiene el botón del ratón presionado).

¿Por qué es importante?

  • Feedback inmediato: El usuario sabe que su clic fue registrado
  • Sensación táctil: Simula la sensación de presionar un botón físico
  • Mejora la experiencia: Hace la interfaz más responsive y natural

Ejemplo completo con todas las pseudo-clases

.btn {  background: #0066cc;  color: white;  padding: 12px 24px;  border: none;  border-radius: 5px;  cursor: pointer;  transition: all 0.2s;  /* Al pasar el ratón */  &:hover {    background: #0052a3;    transform: translateY(-2px);    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);  }  /* Al recibir el foco (con teclado) */  &:focus {    outline: 2px solid #0066cc;    outline-offset: 2px;  }  /* Al hacer clic */  &:active {    background: #003d7a;    transform: translateY(0);    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);  }}

:disabled - Cuando está deshabilitado

La pseudo-clase :disabled se aplica a elementos de formulario que tienen el atributo disabled.

¿Por qué es importante?

  • Indica que no está disponible: El usuario sabe que no puede interactuar con el elemento
  • Previene acciones: Visualmente muestra que el elemento no responderá
  • Mejora la UX: Evita confusión sobre qué elementos son interactivos

Ejemplo básico

<button>Botón activo</button><button disabled>Botón deshabilitado</button><input type="text" placeholder="Campo activo" /><input type="text" disabled placeholder="Campo deshabilitado" />
button {  &:hover {    background: darkblue;  }  &:disabled {    background: #ccc;    color: #666;    cursor: not-allowed;    opacity: 0.6;  }  /* Importante: hover NO debe aplicarse si está disabled */  &:disabled:hover {    background: #ccc; /* Se mantiene igual */  }}input {  border: 2px solid #ccc;  padding: 10px;  &:disabled {    background: #f5f5f5;    color: #999;    cursor: not-allowed;  }}

La propiedad pointer-events: none

Cuando un elemento está deshabilitado, además de cambiar su apariencia visual, a veces queremos desactivar completamente todas las interacciones con ese elemento. Para esto usamos pointer-events: none.

¿Qué hace pointer-events: none?

La propiedad pointer-events controla si un elemento puede ser el objetivo de eventos del ratón o del puntero. Cuando se establece en none:

  • Ignora todos los clics: El elemento no responde a clics del ratón
  • Ignora hover: No se activará la pseudo-clase :hover
  • No captura eventos: Los eventos del ratón “atraviesan” el elemento
  • El cursor no cambia: No se mostrará el cursor definido en el elemento

Ejemplo práctico

<div class="container">  <button class="disabled-with-pointer-events">No puedes hacer clic aquí</button></div>
.disabled-with-pointer-events {  background: #ccc;  color: #666;  opacity: 0.6;  cursor: not-allowed;  /* Desactiva completamente las interacciones */  pointer-events: none;  /* Este hover nunca se aplicará gracias a pointer-events: none */  &:hover {    background: darkblue; /* No funcionará */  }}

¿Cuándo usar pointer-events: none?

/* Opción 1: Solo estilos visuales */button {  &:disabled {    background: #ccc;    cursor: not-allowed;    opacity: 0.6;    /* Necesitas sobrescribir el hover manualmente */    &:hover {      background: #ccc;    }  }}/* Opción 2: Con pointer-events (más simple) */button {  &:disabled {    background: #ccc;    cursor: not-allowed;    opacity: 0.6;    pointer-events: none; /* Ya no necesitas sobrescribir hover */  }}

Ventajas de pointer-events: none

  1. Más simple: No necesitas sobrescribir :hover, :active, etc.
  2. Más seguro: Garantiza que no habrá interacciones accidentales
  3. Mejor rendimiento: El navegador no procesa eventos en ese elemento

Consideraciones importantes

/* ⚠️ Cuidado: pointer-events afecta también a los elementos hijos */.parent {  pointer-events: none;  /* Los hijos tampoco recibirán eventos */  button {    /* Este botón no responderá a clics */  }}/* ✅ Solución: Reactiva eventos en hijos específicos */.parent {  pointer-events: none;  .active-child {    pointer-events: auto; /* Reactiva los eventos */  }}

Ejemplo completo: Botón con loading

<button class="btn-submit" disabled>  <span class="spinner"></span>  Enviando...</button>
.btn-submit {  background: #0066cc;  color: white;  padding: 12px 24px;  border: none;  cursor: pointer;  &:hover {    background: #0052a3;  }  &:disabled {    background: #ccc;    cursor: not-allowed;    pointer-events: none; /* Desactiva toda interacción */    /* Ya no necesitamos esto gracias a pointer-events: none */    /* &:hover {      background: #ccc;    } */  }}

En resumen: pointer-events: none es una forma más robusta de asegurar que un elemento deshabilitado no responda a ninguna interacción del usuario.

Orden de las pseudo-clases

Cuando usas múltiples pseudo-clases en enlaces, el orden importa. La regla nemotécnica es LVHA (Love Hate):

a {  color: blue;  /* L - Link (estado normal del enlace) */  &:link {    color: blue;  }  /* V - Visited (enlace visitado) */  &:visited {    color: purple;  }  /* H - Hover (al pasar el ratón) */  &:hover {    color: darkblue;  }  /* A - Active (al hacer clic) */  &:active {    color: red;  }}

Si no sigues este orden, algunos estilos pueden no funcionar como esperas.

Otras pseudo-clases útiles

Además de las que hemos visto, hay otras pseudo-clases muy útiles:

/* Primer hijo */li:first-child {  font-weight: bold;}/* Último hijo */li:last-child {  border-bottom: none;}/* Elemento enésimo */li:nth-child(odd) {  background: #f5f5f5;}/* No (negación) */button:not(.primary) {  background: gray;}/* Válido/inválido (formularios) */input:valid {  border-color: green;  &:invalid {    border-color: red;  }}