Desmitificando las pseudo-clases en CSS (:nth-child vs. :nth-of-type)
Spanish (Español) translation by Ana Paulina Figueroa (you can also view the original English article)
Los estilos se aplican a una página web usando selectores de CSS; los selectores te permiten enfocarte en un elemento o conjunto de elementos específicos. Por lo general, al comenzar con CSS harás uso de los selectores de elementos antes de usar clases e IDs.
Si bien estos selectores son poderosos, estos pueden ser bastante limitantes, lo que hace imposible seleccionar un elemento en base a su estado. Si alguna vez has trabajado con frameworks front-end como React y Vue, posiblemente comprendas lo que significa el estado. No me refiero al estado de la aplicación en general, sino al estado de los elementos dentro del código HTML.
El humilde vínculo es un ejemplo simple - puede ser creado usando una etiqueta de anclaje <a>. Entonces el vínculo pueden tener diferentes estados:
- antes de que se haga clic en el vínculo
- cuando un usuario pasa el cursor del ratón sobre el vínculo
- cuando el vínculo ha sido visitado
Los selectores que se usan para gestionar elementos dependiendo de su estado se conocen como pseudo-clases. nth-child y nth-of-type son pseudo-clases que seleccionan un elemento en base a su posición (la posición del elemento también se considera un estado). Echemos un vistazo más de cerca.



Cómo trabajar con :nth-child()
La pseudo-clase nth-child se usa para seleccionar un elemento en base a su posición en una lista de hermanos. Aquí hay aspectos que deben tenerse en consideración:
-
Hermanos: en donde están presentes elementos padres e hijos. Al seleccionar un hermano estás intentando enfocarte en un hijo específico del padre elegido. Un
uly algunoslison ejemplos de un padre y elementos hijos. - La posición del elemento en la lista de sus hermanos se determina en base a los valores que se envían a la pseudo-clase.
Vamos a hacer uso del siguiente código HTML para aprender cómo funciona nth-child.
1 |
<ul>
|
2 |
<li>Ruby</li> |
3 |
<li>Python</li> |
4 |
<li>JavaScript</li> |
5 |
<li>Go</li> |
6 |
<li>PHP</li> |
7 |
<li>Scala</li> |
8 |
<li>Java</li> |
9 |
<li>Kotlin</li> |
10 |
<li>C++</li> |
11 |
<li>C</li> |
12 |
</ul>
|
Existen dos maneras diferentes de especificar la posición del elemento: el uso de palabras clave y notaciones funcionales.
:nth-child(even/odd)
Si usas palabras clave, puedes especificar elementos cuyas posiciones sean un número par (even) o impar (odd), de esta forma:
1 |
ul :nth-child(even) { |
2 |
color: red; |
3 |
}
|
4 |
|
5 |
ul :nth-child(odd) { |
6 |
color: gray; |
7 |
}
|
Esto nos da como resultado lo siguiente:
:nth-child(2)
Cuando especificamos un número en particular (como el 2 en este ejemplo), estamos seleccionando el elemento en la lista de hermanos cuya posición coincide con el número que enviamos. Aquí nos enfocamos en el segundo hijo de la lista no ordenada.
1 |
ul { |
2 |
color: gray; |
3 |
}
|
4 |
|
5 |
ul :nth-child(2) { |
6 |
color: red; |
7 |
}
|
Probablemente puedas imaginar cómo se ve el resultado:
Un error común aquí es que, después de especificar el elemento, quizá agregues un elemento nuevo (como un encabezado) al padre sin darte cuenta de que el elemento seleccionado va a cambiar. Para demostrar esto vamos a agregar un encabezado a la lista de esta forma:
1 |
<ul>
|
2 |
<h3>Programming Languages</h3> |
3 |
<li>Ruby</li> |
4 |
<li>Python</li> |
5 |
<li>JavaScript</li> |
6 |
<li>Go</li> |
7 |
<li>PHP</li> |
8 |
<li>Scala</li> |
9 |
<li>Java</li> |
10 |
<li>Kotlin</li> |
11 |
<li>C++</li> |
12 |
<li>C</li> |
13 |
</ul>
|
A pesar de que, de hecho, este no es un uso válido de HTML, los navegadores aún lo mostrarán bien, y en este caso el primer elemento li será seleccionado, ya que ahora es el segundo hijo de la lista no ordenada.
:nth-child(An)
Muy bien, ahora estamos en un nivel superior. Aquí los elementos (en plural) que seleccionamos se determinarán usando la notación funcional. n denota un contador y A representa el tamaño del bucle, dándonos una secuencia. Por ejemplo, cuando enviamos un valor de 2, se seleccionarán elementos en la secuencia 2, 4, 6 y así sucesivamente:
1 |
ul :nth-child(2n) { |
2 |
color: red; |
3 |
}
|
Para verlo en acción regresemos a nuestro código HTML y agreguemos algunos elementos a la lista. También vamos a hacer que la lista esté ordenada, para poder ver claramente los números de los elementos:
1 |
<ol>
|
2 |
<li>Ruby</li> |
3 |
<li>Python</li> |
4 |
<li>JavaScript</li> |
5 |
<li>Go</li> |
6 |
<li>PHP</li> |
7 |
<li>Scala</li> |
8 |
<li>Java</li> |
9 |
<li>Kotlin</li> |
10 |
<li>C++</li> |
11 |
<li>C</li> |
12 |
<li>Cobol</li> |
13 |
<li>Fortran</li> |
14 |
</ol>
|
Nuestro resultado es el siguiente:
:nth-child(An+B)
Aquí hemos añadido un cálculo adicional a nuestros bucles: +B. Los elementos cuyas posiciones en la lista de hermanos coincidan con el patrón serán seleccionados. Necesitamos saber cómo ocurre el cálculo, así que probemos con una notación funcional como esta:
1 |
ol { |
2 |
color: gray; |
3 |
}
|
4 |
|
5 |
ol :nth-child(3n+1) { |
6 |
color: red; |
7 |
}
|
Esto seleccionará los elementos cuyas posiciones coincidan con 1, 4, 7, 10 y así sucesivamente:
El cálculo comienza a contar desde 0, que es el valor predeterminado de n, y siendo así, los elementos que se van a estilizar serán calculados de esta manera:
- Primer elemento: 3(0) + 1 =
1. - Segundo elemento: 3(1) + 1 =
4. - Tercer elemento: 3(2) + 1 =
7. - Cuarto elemento: 3(3) + 1 =
10.
Piensa en ello como una ecuación algebraica, en la que el valor de n incrementa aritméticamente y el elemento a estilizar es el resultado de la ecuación. Este es otro ejemplo que puedes editar por tu cuenta para ver qué sucede:
1 |
ol :nth-child(3n+2) { |
2 |
color: red; |
3 |
}
|
También puedes usar este método para seleccionar números pares usando la fórmula:
1 |
ol :nth-child(2n+0) { |
2 |
color: red; |
3 |
}
|
Y los números impares pueden seleccionarse usando:
1 |
ol :nth-child(2n+1) { |
2 |
color: red; |
3 |
}
|
Cómo trabajar con :nth-of-type()
En todos los ejemplos que hemos visto para la pseudo-clase nth-child, es importante notar que el objetivo es seleccionar elementos en una lista de hermanos. Esto no toma en cuenta el tipo del elemento. Para garantizar que la selección también llegue a un tipo particular, podemos hacer uso de la pseudo-clase nth-of-type.
Para ver esto en funcionamiento, vamos a editar el código HTML para que se vea así (de nuevo, esto es técnicamente un mal uso de HTML, pero los navegadores lo interpretarán sin problemas):
1 |
<ol>
|
2 |
<p>This is a first paragraph<p> |
3 |
<li>Ruby</li> |
4 |
<li>Python</li> |
5 |
<li>JavaScript</li> |
6 |
<li>Go</li> |
7 |
<li>PHP</li> |
8 |
<p>Here is a paragraph</p> |
9 |
<li>Java</li> |
10 |
<li>Kotlin</li> |
11 |
<li>C++</li> |
12 |
<li>C</li> |
13 |
<li>Cobol</li> |
14 |
<li>Fortran</li> |
15 |
</ol>
|
Para seleccionar los elementos li cuyas posiciones correspondan a un número impar, podemos hacer esto,
1 |
ol li:nth-of-type(odd) { |
2 |
color: red; |
3 |
}
|
lo que nos da como resultado:
Para seleccionar los elementos li cuyas posiciones correspondan con un número par, haríamos lo siguiente
1 |
ol li:nth-of-type(even) { |
2 |
color: red; |
3 |
}
|
Quizá pienses que el uso de nth-child sería igual de efectivo siempre que especifiques el li, por ejemplo:
1 |
ol li:nth-child(odd) { |
2 |
color: red; |
3 |
}
|
pero ese no es el caso. ¡Inténtalo tú mismo!
Conclusión
Estas pseudo-clases son útiles cuando tienes que seleccionar elementos específicos en una lista de hermanos. Para aprender más sobre ellas, consulta los documentos web de MDN acerca de nth-child() y nth-of-type().
Más fundamentos de CSS
Obtén más información sobre CSS y los selectores de CSS con estas fundamentales guías:









