Menu

Pseudoclases CSS: nth-child, not, first-child, focus

Las pseudoclases seleccionan elementos por posición o por estado: :nth-child(), :first-child, :not(), :focus, :checked, :has() y más. Aprende la sintaxis, la fórmula an+b con un probador en vivo y la diferencia entre nth-child y nth-of-type.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Qué es una pseudoclase

Una pseudoclase es una palabra clave después de dos puntos que selecciona elementos por su posición en el documento o por su estado. La agregas a un selector normal: li:first-child, input:focus, a:hover.

Las pseudoclases de estado para enlaces y el mouse (:hover, :active, :visited) tienen su propia página, hover en CSS.

:nth-child() y la fórmula an+b

:nth-child() acepta un número, una palabra clave o una fórmula an+b. El navegador prueba n = 0, 1, 2, ... y selecciona cada posición que produce la fórmula (las posiciones empiezan en 1).

FórmulaPosiciones que seleccionaSignificado
33El tercer hijo
odd o 2n+11, 3, 5, ...Filas impares
even o 2n2, 4, 6, ...Filas pares
3n3, 6, 9, ...Uno de cada tres
n+44, 5, 6, ...El cuarto y los siguientes
-n+31, 2, 3Los tres primeros
3n+11, 4, 7, ...Uno de cada tres, empezando por el primero

Escribe una fórmula y mira qué elementos coinciden:

Prueba odd, even, 4, n+7, -n+5 y 2n+3. Una fórmula inválida no selecciona nada.

Su gemela que cuenta desde el final es :nth-last-child(): li:nth-last-child(-n+2) selecciona los dos últimos elementos.

nth-child vs nth-of-type

:nth-child() cuenta todos los elementos hermanos, sea cual sea su etiqueta, y solo después comprueba el resto del selector. :nth-of-type() cuenta solo los hermanos con la misma etiqueta. La diferencia se nota en cuanto los hermanos están mezclados:

Existen los mismos pares para los extremos: :first-child / :first-of-type, :last-child / :last-of-type, :only-child / :only-of-type.

:not(), :is() y :where()

PseudoclaseEjemploSelecciona
:not(X)li:not(.done)Elementos que no coinciden con X
:is(X, Y):is(h1, h2, h3) aElementos que coinciden con cualquiera de la lista
:where(X, Y):where(ul, ol) liIgual que :is(), con especificidad cero
:has(X)li:has(> input:checked)Elementos que contienen algo que coincide con X

:not() es la que se usa a diario, por ejemplo para poner un separador entre elementos pero no después del último:

Pseudoclases de estado: focus, checked, disabled, invalid

PseudoclaseSelecciona
:focusEl elemento que tiene el foco del teclado o del mouse
:focus-visibleCon foco, y el navegador decide que debe verse un anillo (normalmente con el teclado)
:focus-withinUn elemento que contiene al elemento con foco
:checkedUn checkbox o radio marcado, o una <option> seleccionada
:disabled / :enabledControles de formulario que están (o no) deshabilitados
:required / :optionalInputs con o sin required
:invalid / :validInputs cuyo valor no pasa o pasa la validación
:user-invalidInválido, pero solo después de que el usuario interactuó con él
:placeholder-shownUn input que en ese momento muestra su placeholder
:emptyUn elemento sin hijos, ni siquiera texto
:targetEl elemento cuyo id coincide con el #fragment de la URL

Haz clic en el campo de email: su label se vuelve azul gracias a :focus-within. Escribe algo que no sea un email y sal del campo: :user-invalid pone el borde ámbar. Un :invalid simple habría marcado en ámbar el campo obligatorio vacío antes de que lo tocaras.

Hagas lo que hagas con :focus, mantén un estilo de foco visible. Quitar el outline sin reemplazarlo deja a los usuarios de teclado sin saber dónde están.

:has(), el selector de padre

:has() selecciona un elemento según lo que contiene. Es el "selector de padre" que se pidió durante años, y funciona en las versiones actuales de Chrome, Firefox y Safari.

Elige el otro plan: toda la tarjeta sigue al radio button, sin JavaScript.

Errores comunes

  • Un espacio antes de los dos puntos. li :first-child significa "un primer hijo dentro de un li". Escribe li:first-child.
  • Esperar que p:nth-child(1) signifique "el primer p". Significa "el primer hijo, si es un p". Usa :first-of-type para el primer p.
  • Contar desde 0. Las posiciones empiezan en 1: :nth-child(0) no selecciona nada.
  • Quitar los outlines de foco. :focus { outline: none } sin reemplazo rompe la navegación con teclado.
  • Confundir : y ::. :before es una forma antigua de escribir el pseudoelemento ::before; las pseudoclases siempre usan un solo signo de dos puntos.

Preguntas frecuentes

¿Qué es una pseudoclase en CSS?

Una palabra clave después de dos puntos que selecciona elementos por su estado o posición y no por su nombre, como a:hover, li:first-child o input:focus. Se agrega a un selector normal, y la mayoría de las pseudoclases cuentan como una clase en la especificidad (:where() cuenta cero).

¿Cómo funciona nth-child en CSS?

:nth-child(an+b) selecciona los elementos cuya posición entre sus hermanos es a×n+b para n = 0, 1, 2 y así sucesivamente, contando desde 1. :nth-child(3) es el tercer hijo, :nth-child(odd) o 2n+1 todos los impares y :nth-child(n+4) el cuarto y los siguientes.

¿Qué diferencia hay entre nth-child y nth-of-type?

:nth-child() cuenta todos los elementos hermanos y después comprueba el resto del selector; :nth-of-type() cuenta solo los hermanos del mismo tipo de elemento. En una lista con un h2 seguido de párrafos, p:nth-child(1) no selecciona nada, mientras que p:nth-of-type(1) selecciona el primer párrafo.

¿Cómo se usa :not() en CSS?

Pon entre paréntesis el selector que quieres excluir: li:not(.done) selecciona todos los elementos de lista sin la clase done. También acepta una lista, input:not([type="checkbox"], [type="radio"]).

¿Qué diferencia hay entre una pseudoclase y un pseudoelemento?

Una pseudoclase (un signo de dos puntos, :hover) selecciona un elemento existente completo en cierto estado. Un pseudoelemento (dos signos de dos puntos, ::before) apunta a una parte de un elemento o crea contenido generado.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR