Quem tem medo do nth-child?
Caio Marcellus Cabral
Posted on April 3, 2023
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)
Talvez a sua primeira reação seja essa daqui:
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????
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)
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; }
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;
}
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!
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!
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;
}
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;
}
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
Posted on April 3, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024