Cambiar el color de un enlace al pasar el ratón, marcar en verde un campo de formulario bien rellenado o alternar el fondo de las filas de una tabla no requiere ni una línea de JavaScript. Todo eso lo resuelven las pseudo-clases de CSS: aplican estilos según el estado o la posición de un elemento, sin tocar el HTML.
Qué es exactamente una pseudo-clase
Una pseudo-clase es una palabra clave que se añade a un selector de CSS para apuntar a un estado concreto de un elemento. Por ejemplo, :hover aplica estilos cuando el cursor pasa por encima. A diferencia de una clase normal escrita en el HTML, el navegador decide cuándo se activa una pseudo-clase según la interacción del usuario o la estructura del documento.
Los tres grandes grupos de pseudo-clases
1. Dinámicas: reaccionan a lo que hace el usuario
Se activan por una acción directa, sin necesidad de JavaScript:
:hover: se aplica cuando el cursor pasa por encima del elemento.a:hover { color: red; }:focus: se activa cuando un campo de formulario recibe el foco.input:focus { border: 2px solid blue; }:active: se aplica mientras se está pulsando el elemento, como al hacer clic en un botón.button:active { background-color: green; }
2. Estructurales: dependen de la posición en el DOM
Permiten seleccionar elementos según su lugar en el árbol del documento, sin añadir clases extra en el HTML:
:first-child: selecciona el primer hijo de su padre.p:first-child { font-weight: bold; }:last-child: selecciona el último hijo de su padre.li:last-child { margin-bottom: 0; }:nth-child(n): selecciona el enésimo hijo, dondenpuede ser un número, una palabra clave o una fórmula.tr:nth-child(even) { background-color: #f2f2f2; }
3. De estado: reflejan cómo está un elemento ahora mismo
Especialmente útiles en formularios y enlaces:
:checked: aplica estilos a elementos marcados o seleccionados.input[type="checkbox"]:checked { accent-color: green; }:disabled: se aplica a elementos de formulario deshabilitados.button:disabled { opacity: 0.5; }:validy:invalid: indican si un campo cumple las reglas de validación.input:valid { border-color: green; } input:invalid { border-color: red; }
Estas últimas son clave si trabajas la accesibilidad anticipada de un formulario: avisar visualmente de un error antes de enviar el formulario evita frustración al usuario.
Pseudo-clases frente a pseudo-elementos
Ambos empiezan por «pseudo», pero no hacen lo mismo. Las pseudo-clases apuntan a estados de elementos que ya existen en el HTML. Los pseudo-elementos, en cambio, dan estilo a una parte concreta de un elemento o incluso generan contenido que no está en el HTML: ::before y ::after insertan contenido antes o después del contenido real.
Combinando pseudo-clases y pseudo-elementos
Juntar ambos permite efectos que por separado no conseguirías. Por ejemplo, para agrandar la primera letra de un párrafo solo cuando el cursor pasa por encima:
p:hover::first-letter {
font-size: 2em;
color: blue;
}
Aquí :hover detecta la interacción del usuario y ::first-letter aplica el estilo solo a la primera letra del párrafo. Este tipo de detalle es justo lo que hace que una interfaz se sienta cuidada, algo que analizamos con más ejemplos en nuestro artículo sobre qué son las microinteracciones.
Dominar las pseudo-clases te permite resolver con CSS puro cosas que muchos resuelven con JavaScript de más, lo que se traduce en código más ligero y fácil de mantener a largo plazo.
Preguntas frecuentes
¿Las pseudo-clases funcionan igual en todos los navegadores?
Las más comunes (:hover, :focus, :nth-child) tienen soporte universal desde hace años. Algunas más recientes conviene comprobarlas en caniuse.com antes de depender de ellas en producción.
¿Puedo combinar varias pseudo-clases en un mismo selector?
Sí. Por ejemplo, input:focus:invalid aplica un estilo solo cuando el campo tiene el foco y además no es válido, algo muy útil para dar feedback en tiempo real.
¿El :hover tiene sentido en dispositivos táctiles?
Tiene un comportamiento distinto, porque no existe un cursor real. Muchos navegadores móviles lo simulan al primer toque, pero no debes depender de él para funciones esenciales en móvil.
¿Qué diferencia hay entre :nth-child y :nth-of-type?
:nth-child cuenta la posición entre todos los hermanos, sea cual sea su etiqueta. :nth-of-type solo cuenta los hermanos que comparten la misma etiqueta, lo que evita sorpresas cuando el HTML mezcla distintos tipos de elementos.





