Aprende a usar pseudo-clases en CSS para estilizar elementos según su estado
midudev
Más clases y directos en YouTube
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
- Más simple: No necesitas sobrescribir
:hover,:active, etc. - Más seguro: Garantiza que no habrá interacciones accidentales
- 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; }}