DEV Community

Caio Marcellus Cabral
Caio Marcellus Cabral

Posted on

Quem tem medo do nth-child?

Digamos que você precisa dar manutenção em um código na empresa em que você trabalha, e se depara com isso daqui no CSS:

li:nth-child(n + 2):nth-child(-n + 9):nth-child(4n + 2)
Enter fullscreen mode Exit fullscreen mode

Talvez a sua primeira reação seja essa daqui:

Meme Nothing to do here em que desenho de pessoa está fugindo com uma mochila voadora de uma situação desconfortável

Palma, palma, não priemos cânico! Pega um café e vamos destrinchar passo a passo de como esse megazord funciona. Depois de ler esse artigo você vai entender e apreciar essa ferramenta poderosa que é a pseudo-classe :nth-child(). Ficou na dúvida do que é uma pseudo-classe? Dá uma olhada no artigo da @sucodelarangela que está lá nas referências. Mas, em linhas gerais, é só lembrar da partícula “pseudo” que a gente viu na escola (pseudociências, pseudofrutos), que significava aquilo que parece ser, mas não é. As pseudo-classes são seletores do CSS que ajudam a mirar em certos elementos sem necessidade de criar uma classe específica para eles.

Vamos estudar alguns casos?

1 – Usando :nth-child() com um número absoluto

Aqui a coisa é bem intuitiva: você seleciona o elemento que é o enésimo filho dentro de outro.

Enésimo????

Meme da Nazaré em que a personagem de uma novela olha para cálculos complexos com perplexidade

Tá, talvez fique mais fácil com exemplos, né? É o seguinte: se você colocar :nth-child(1), vai selecionar o primeiro elemento, :nth-child(2), o segundo, e assim por diante.

No exemplo abaixo eu usei o seletor

.filho:nth-child(3)
Enter fullscreen mode Exit fullscreen mode

para pintar o terceiro quadrado de verde.

O que está acontecendo aqui: estamos selecionando o elemento com classe "filho" que também seja o terceiro filho de outro elemento. E isso é muito importante, como vamos ver a seguir.

Um erro muito comum é pensar “Eu quero o terceiro elemento com a classe ‘filho’” e usar o nth-child. Veja o exemplo abaixo:

No primeiro cenário, estamos tentando mirar no elemento com classe filho que seja o terceiro filho de algum elemento. Acontece que nesse caso, o terceiro filho é uma tag p sem a classe “filho”. Então o CSS não encontra ninguém para pintar de verde.

No segundo cenário, corrigimos usando nth-child(4), mas a correção vai depender de qual o nosso objetivo (poderia ser aplicar ‘.pai > :nth-child(3)’, ou mesmo ‘:nth-of-type(3)’, atingindo resultados diferentes).

Aí você que leu até aqui pensa “Que moleza! Já entendi, nem vou ler o resto” e corre pro seu projeto querendo estilizar aquela lista de links. Com a segurança de quem sabe que CSS se aprende em 30 minutos, você digita:

.lista__item__link:nth-child(3){ color: red;  }
Enter fullscreen mode Exit fullscreen mode

Ao ver que não funcionou, com lágrimas nos olhos, você corre para o twitter e lança a hashtag #ocaiomentiupramim.

Mas calma lá. Vamos entender o que aconteceu aqui hipotética pessoa apressada.

Sua lista de links tem mais ou menos essa cara aqui:

O que acontece é que você estava dizendo pro CSS: “Corre lá, e busca o 'lista__item__link' que seja o terceiro filho de alguém”. O CSS foi e só encontrou “lista__item__link” que era o primeiro filho do “lista__item”. Ele ficou bem confuso, e com um balde de tinta vermelha inutilizado.

Agora você já entendeu e já sabe como consertar: é só mirar no terceiro “lista__item”, e depois selecionar o filho dele.

.lista__item:nth-child(3) > .lista__item__link{
  color: red;  
}
Enter fullscreen mode Exit fullscreen mode

Até agora os exemplos que vimos não parecem tão úteis. Como estamos mirando em apenas um elemento, todas as vezes seria possível utilizar classes sem prejuízo da manutenibilidade do código. E se precisássemos aplicar uma ação nos elementos múltiplos de 3? Você precisaria aplicar várias vezes aquela classe no HTML. Daria para usar nth-child(3), nth-child-(6), nth-child-(9), nth-child(12), mas e se você não soubesse de antemão quantos elementos vão estar naquela lista?

É aí que o nth-child começa a brilhar.

2 – Usando múltiplos

Quando usamos o ‘n’ do nth-child, é como se substituíssemos esse ‘n’ por cada posição dos elementos filhos. Uma ul que tenha 6 li’s, e na qual colocássemos o seletor “li:nth-child(2n)” faria por trás dos panos algo assim:

li:nth-child(2 * 1), logo li:nth-child(2);
li:nth-child(2 * 2), logo li:nth-child(4);
li:nth-child(2 * 3) , logo li:nth-child(6);
...
li:nth-child(2 * 6) , logo li:nth-child(12);

Então ele iria selecionar o 2º, 4º e 6º elementos.

Digamos que a gente precise pintar todo o terceiro quadrado de uma lista de 20 quadrados de verde. Agora a gente já consegue fazer isso bem fácil:

Agora, e se a gente precisasse fazer isso, só que começando do primeiro? No caso, pintar o primeiro e depois ir pulando de três em três (4º, 7º, etc)?

3 – Adicionando deslocamento

Bem , nós já sabemos fazer a seleção do 3º, 6º, 9º... certo?

Agora compare essas duas seleções:

0º, 3º, 6º, 9º...
1º, 4º, 7º, 10º...

A diferença entre elas é que na segunda, em vez de começarmos do zero, começamos do número 1

Para fazermos isso com nth-child basta a gente somar o deslocamento que a gente quer ao múltiplo de 'n'. Nesse caso, nth-child(3n + 1).

Na dúvida, substitua o n pelo número de elementos, em sequência, começando do zero.

nth-child(3n + 1) =>
nth-child(3 * 0 + 1), logo nth-child(1);
nth-child(3 * 1 + 1), logo nth-child(4);
nth-child(3 * 2 + 1), logo nth-child(7);
...
nth-child(3 * 20 + 1), logo nth-child(61);

Isso também pode ser usado para mirar em todos os elementos menos alguns do início. Digamos que a gente quer pintar todos os quadrados de verde, menos os três primeiros.

Se usássemos “nth-child(n)” estaríamos dizendo para selecionar todos os elementos. Se somássemos 1, o resultado seria... o mesmo!

Cachorrinho decepcionado

Aqui temos que entender o pulo do gato do nth-child: a contagem dele começa do 0. Então, quando somamos 1, não vamos ver diferença no resultado. Temos sempre que pensar um número à frente para compensar esse primeiro “n-fantasma”.

É só fazer aquela substituição marota:
nth-child(n + 1) =>
nth-child(0 + 1), logo nth-child(1);
nth-child(1 + 1), logo nth-child(2);
nth-child(2 + 1), logo nth-child(3);
...
nth-child(20 + 1), logo nth-child(21);

Com isso, podemos concluir que para pular os três primeiros elementos, temos que somar 4, usando nth-child(n + 4). Podemos ainda pensar da seguinte forma: usando nth-child(n + 4) estamos selecionando do 4º elemento em diante,

Um outro pulo do gato do nth-child: a contagem do 'n' na verdade não para na quantidade de elementos da lista. Por isso um seletor como nth-child(n - 5), que poderia servir para selecionar todos os itens, menos os cinco últimos não funciona. Esse seletor vai selecionar TODOS os elementos. Mas a gente consegue contornar isso.

4 –Olhando só para os primeiros

No tópico anterior, aprendemos a olhar para todos menos para os primeiros com a notação nth-child(n + X). Podemos fazer o inverso disso, e mirar somente nos primeiros X elementos e não no resto.
Para isso, usamos “-n”. Não se assuste, é tão fácil quanto os outros!

Quando declaramos nth-child(-n), não vamos ver nada acontecendo. Isso porque por trás dos panos o CSS vai fazer numa lista, por exemplo, de 6 itens:

nth-child(-n) =>
nth-child(-1 * 0), logo nth-child(0);
nth-child(-1 * 1), logo nth-child(-1);
nth-child(-1 * 2), logo nth-child(-1);
...
nth-child(-1 * 6), logo nth-child(-6);
...

Como não temos elementos negativo no nth-child, nenhum será selecionado.

Mas se somarmos ao “-n” uma quantidade X, podemos selecionar quantos elementos do início da lista nós quisermos!

nth-child(-n + 3) =>
nth-child(-1 * 0 + 3), logo nth-child(3);
nth-child(-1 * 1 + 3), logo nth-child(2);
nth-child(-1 * 2 + 3), logo nth-child(1);
...
nth-child(-1 * 6 + 3), logo nth-child(-3);
...

Note que nesse caso nós vamos selecionar os três primeiros elementos. Logo, podemos pensar que o seletor nth-child(-n + 3) está dizendo “selecionar todos, mas só até o terceiro elemento”.

Veja ainda o exemplo abaixo:

5 –Montando nosso Megazord

Agora estamos prontos para montar o nosso nth-child monstrão!

Meme com fisiculturista dizendo "Tá saindo da jaula o monstro"

Digamos que a gente queira selecionar a partir do sétimo quadrado, e parar no décimo-quinto.

Para fazer isso a gente pode encadear seletores nth-child!

.container__square:nth-child(n + 7):nth-child(-n + 15){
  background-color: green;
}
Enter fullscreen mode Exit fullscreen mode

Assim, estamos falando pro CSS: “Vai lá, e pinta de verde todos os quadrados a partir do sétimo, mas não vá além do décimo quinto”.

E se agora nós quiséssemos fazer a mesma coisa, mas pulando um?

.container__square:nth-child(n + 7):nth-child(-n + 15):nth-child(2n + 1){
  background-color: green;
}
Enter fullscreen mode Exit fullscreen mode

Jesse Pinkman da série Breaking Bad falando "Ciência!"

Conseguimos!

Aquele emaranhado que parecia indecifrável agora parece bem mais simpático, não é?

Utilizando nth-child nos seus projetos você consegue criar seletores complexos sem poluir seu código com classes muito específicas, que tornariam difícil a inserção de novos elementos em uma lista, por exemplo.

Parabéns por ter mais uma ferramenta no seu cinto de utilidades.

Referências:

:nth-child
https://css-tricks.com/almanac/selectors/n/nth-child/

:nth-child()
https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child

How does CSS nth-child() really work?
https://www.youtube.com/watch?v=KIIktcWu6hc&ab_channel=WesBos

Entendendo CSS: Pseudo-Classes e Pseudo-Elementos
https://dev.to/sucodelarangela/entendendo-css-pseudo-classes-e-pseudo-elementos-b83

Top comments (4)

Collapse
 
sucodelarangela profile image
Angela Caldas

Boa! Tem hora nth-child dá realmente uma embolada na mente, mas teu artigo já vai ser uma excelente fonte de referência pra muita gente! Parabéns!

Collapse
 
fabianoraiser profile image
Fabiano Raiser

Minhas listas não serão mais as mesmas! E o melhor foi que vc explicou tudo de uma forma leve que não pesou nada no raciocínio.

Collapse
 
ramoscarloseduardo profile image
Carlos Eduardo Ramos

Tem uns exemplos aí de como fazer errado que pareciam cópia de umas tentativas minhas kkkk muito legal o artigo, o tom descontraído ajuda a não desistir de construir esse Megazord!

Collapse
 
monicahillman profile image
Monica Hillman

Muito bom artigo! Muitas vezes fiquei indo na tentativa e erro com o nth-child e é bom entender um pouco a mais. O tom de humor deixou 10/10