Pseudo-clases
Fundamentos de CSS
Las pseudo-clases son selectores que apuntan a un estado o posición de un elemento que no existe como atributo en el HTML, como :hover cuando el cursor está encima, :focus cuando tiene el foco, o :nth-child() para seleccionar por posición.
Una pseudo-clase es un tipo especial de selector que apunta a un elemento según su estado actual o su posición en el árbol DOM — información que no está escrita en el HTML como un atributo, sino que el navegador calcula dinámicamente. La sintaxis es un : seguido del nombre de la pseudo-clase, pegado al selector al que se agrega.
Lo que hace únicas a las pseudo-clases es que el estado que describen cambia en tiempo de ejecución, sin modificar el HTML. Cuando el usuario pasa el cursor sobre un botón, ese botón entra en el estado :hover — no porque el HTML haya cambiado, sino porque el navegador detecta la posición del mouse y activa esa pseudo-clase. Cuando el usuario hace clic en un input, ese input entra en :focus. El CSS puede reaccionar a esos estados para crear interfaces interactivas sin una sola línea de JavaScript.
Las pseudo-clases son también una herramienta estructural: pseudo-clases como :first-child, :last-child y :nth-child() seleccionan elementos por su posición dentro de un contenedor, lo que permite estilizar listas, tablas y grillas según la posición de cada ítem sin necesidad de agregar clases al HTML. Esto es especialmente poderoso cuando el HTML es generado dinámicamente o viene de un CMS.
Cómo funciona
Pseudo-clases de estado de interacción
Estas pseudo-clases responden a acciones del usuario y son la base de las interfaces interactivas en CSS puro.
:hover — el cursor del mouse está sobre el elemento. Aplica solo a dispositivos con mouse (no a pantallas táctiles sin hover real). Típicamente usado para cambiar color de fondo, mostrar menús desplegables, resaltar filas de tabla.
a:hover { color: teal; }
.boton:hover { background-color: darkblue; }
:focus — el elemento tiene el foco del teclado (navegación por Tab) o fue activado con clic en elementos de formulario. Crítico para accesibilidad: nunca elimines el outline de :focus sin reemplazarlo con un indicador visual igualmente claro.
input:focus { outline: 2px solid blue; }
a:focus { outline: 2px dashed currentColor; }
:active — el elemento está siendo activado (durante el clic o la pulsación de tecla). Dura solo el instante de la interacción.
button:active { transform: scale(0.97); }
:visited — para enlaces <a>, aplica cuando el usuario ya visitó esa URL. Por razones de privacidad, los navegadores limitan qué propiedades pueden cambiarse con :visited (solo color y algunas propiedades de background).
a:visited { color: purple; }
Nota sobre preview:
:hover,:focusy:activeson estados dinámicos que no se pueden mostrar en un bloque de resultado estático. Para verlos, probá el código en el sandbox del recorrido o en DevTools (pestaña “Styles” → forzar estado).
Pseudo-clases estructurales
Seleccionan elementos según su posición en el árbol DOM, sin importar sus atributos o clases.
:first-child — el elemento que es el primer hijo de su padre.
li:first-child { font-weight: bold; }
:last-child — el elemento que es el último hijo de su padre.
li:last-child { border-bottom: none; }
:nth-child() — selecciona hijos según una fórmula. Es la pseudo-clase estructural más potente.
li:nth-child(2) { color: red; } /* el segundo hijo */
li:nth-child(odd) { background: #f1f5f9; } /* hijos impares: 1, 3, 5... */
li:nth-child(even) { background: #e2e8f0; } /* hijos pares: 2, 4, 6... */
li:nth-child(3n) { color: blue; } /* cada tercer hijo: 3, 6, 9... */
li:nth-child(3n+1) { color: green; } /* 1, 4, 7, 10... */
La fórmula an+b
La fórmula completa de :nth-child() es an+b, donde:
aes el paso (cada cuántos hijos se selecciona uno)nes un contador que empieza en 0 y sube de 1 en 1 (0, 1, 2, 3…)bes el desplazamiento inicial (cuál es el primer hijo seleccionado)
Ejemplos calculados:
:nth-child(2n)→a=2, b=0→ n=0: 0, n=1: 2, n=2: 4… → pares (equivale aeven):nth-child(2n+1)→ n=0: 1, n=1: 3, n=2: 5… → impares (equivale aodd):nth-child(3n+2)→ n=0: 2, n=1: 5, n=2: 8… → 2, 5, 8…:nth-child(n+4)→a=1, b=4→ selecciona desde el 4to hijo en adelante
Gotchas conceptuales
:hoverno funciona en móvil (táctil). En pantallas táctiles sin stylus, el estado hover no existe o se comporta de manera inconsistente. Nunca pongas funcionalidad crítica (como un menú desplegable) solo en:hover.:focusno lo elimines sin reemplazarlo. Quitar el outline conoutline: noneen:focuses un error de accesibilidad grave — los usuarios que navegan con teclado pierden toda indicación visual de dónde está el foco. Si el outline por defecto es feo, reemplazalo conoutline: 2px solid currentColoro unbox-shadowvisible.:nth-child()cuenta todos los hijos, no solo los del tipo.li:nth-child(2)selecciona el<li>que es el segundo hijo de su padre — si el segundo hijo no es un<li>, no se aplica. Para seleccionar el segundo<li>independientemente de su posición, usá:nth-of-type(2).- La especificidad de una pseudo-clase equivale a una clase.
:hover,:focus,:nth-child()tienen la misma especificidad que.clase. Esto es importante cuando competís contra reglas con class selectors. :first-childvs:first-of-type.:first-childrequiere que el elemento sea el primer hijo de su padre (cualquier tipo).:first-of-typerequiere que sea el primer elemento de ese tipo entre sus hermanos. Son distintos y se confunden con frecuencia.
Vigente / legacy
Todas las pseudo-clases mencionadas son vigentes y con soporte universal. :nth-child(), :first-child y :last-child son CSS3 — soporte universal desde IE9+. La variante funcional de :nth-child() con selector (li:nth-child(2n of .destacado)) es más nueva (Baseline 2023) y tiene soporte amplio en browsers modernos pero no en IE. Para este nivel, la forma sin of es la que importa.