Quem tem medo do nth-child?
Published: 2023-04-03 16:34:53

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:

```css
li:nth-child(n + 2):nth-child(-n + 9):nth-child(4n + 2)
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qlr01g4ci7bsdplmjc8j.jpg)


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbdbu9updc3nk1si3g9w.jpg)

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 
```css
.filho:nth-child(3)
```
para pintar o terceiro quadrado de verde.

{% codepen https://codepen.io/marcelluscaio/pen/rNZEvKL %}

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:

{% codepen https://codepen.io/marcelluscaio/pen/NWLQxYo %}

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:

```css
.lista__item__link:nth-child(3){ color: red;  }
```

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:

{% codepen https://codepen.io/marcelluscaio/pen/ExeqPeg %}

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.

```css
.lista__item:nth-child(3) > .lista__item__link{
  color: red;  
}
```

{% codepen https://codepen.io/marcelluscaio/pen/RwYXrey %}

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:

{% codepen https://codepen.io/marcelluscaio/pen/WNgVrYB %}

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);

{% codepen https://codepen.io/marcelluscaio/pen/wvEVmoo %}

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jxpmyxqez10ja9ela2b0.jpg)

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,

{% codepen https://codepen.io/marcelluscaio/pen/jOvgzmG %}

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:

{% codepen https://codepen.io/marcelluscaio/pen/eYLqMPQ %}

## 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"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ablqjf74w0a2sfx6lc46.jpg)

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!

```css
.container__square:nth-child(n + 7):nth-child(-n + 15){
  background-color: green;
}
```

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”.

{% codepen https://codepen.io/marcelluscaio/pen/eYLqrmo %}

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

```css
.container__square:nth-child(n + 7):nth-child(-n + 15):nth-child(2n + 1){
  background-color: green;
}
```

{% codepen https://codepen.io/marcelluscaio/pen/VwGoxjm %}


![Jesse Pinkman da série Breaking Bad falando "Ciência!"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qgd6bzpk9lqufk9evxn.jpg)

### 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