Gabriel / Ramos

⟨ pintor de pixel ⟩

  • Blog
  • Usando :not e :empty para exceções em CSS

Usando :not e :empty para exceções em CSS

Com certeza vai te ajudar a evitar algumas sobrescritas enquanto escreve seus estilos e melhorar a legibilidade do seu código

3 min. de leitura

Foto por Tina Floersch

Percebi que tenho vários posts sobre React e JS em geral, e como parte importante na rotina enquanto estamos desenvolvendo, achei que estava na hora de começar a escrever um pouco sobre nosso tão amado (e odiado por muitos também) CSS.

Para começar, pensei em dois seletores que tem sido uma mão na roda naqueles cenários onde eu preciso aplicar um estilo específico a vários elementos, exceto um (geralmente o último ou primeiro de uma lista) ou elementos vazios: os seletores de pseudo-classe :not e :empty.

:not

Com um exemplo acho que fica mais fácil de ver sua utilização, vamos pensar que você precisa fazer os estilos de uma lista parecida com a listagem aqui do blog, algo como:

Listagem de posts

Conseguimos perceber que tem um estilo padrão que se repete em todos os elementos da listagem, exceto por um único detalhe: aquelas linhas (vamos chamar de bordas) só existem entre dois elementos da listagem.

Pra resolver esse cenário, classicamente, seria só colocar uma borda em todos os elementos e remover essa mesma borda no primeiro ou no último, tendo algo como:

/*
 vamos imaginar que os elementos da lista
 possuem a classe "post-item", ok?
*/

/*
 no caso de preferir inserir como border-top
 e remover do primeiro item, seria algo como:
*/
.post-item {
  border-top: 1px dashed #1F1E1E;
}

.post-item:first-child {
  border-top: 0;
}

/* -------------------- */

/*
 no caso de preferir inserir como border-bottom
 e remover do último item, seria algo como:
*/
.post-item {
  border-bottom: 1px dashed #1F1E1E;
}

.post-item:last-child {
  border-bottom: 0;
}

Nesse caso, conseguimos inserir um estilo em todos os elementos da lista exceto o primeiro (:first-child) ou último (:last-child), dependendo da decisão por usar border-top ou border-bottom.

A questão nesses dois casos é que você precisaria, explicitamente, remover essa borda aplicada e sobrescrever uma regra CSS em específico para um único elemento. Não tem nada de errado nisso e funciona perfeitamente! Entretanto, ainda assim é um pequeno "retrabalho" pra fazer esse estilo funcionar da forma correta.

Em casos como esse que o seletor de pseudo-classe :not funciona muito bem!

A ideia com esse seletor é justamente fazer essa "negativa" numa regra CSS: aplicar estilo a todos os elementos exceto ao que satisfazem alguma regra definida por você (no caso, :first-child ou :last-child), podendo ser combinado com outros seletores CSS.

Sua utilização é bem simples, se adaptássemos o exemplo anterior para utilizar :not, teríamos algo como:

/*
 no caso de preferir inserir como border-top
 exceto no primeiro item, seria algo como:
*/
.post-item:not(:first-child) {
  border-top: 1px dashed #1F1E1E;
}

/* -------------------- */

/*
 no caso de preferir inserir como border-bottom
 exceto no último item, seria algo como:
*/
.post-item:not(:last-child) {
  border-bottom: 1px dashed #1F1E1E;
}

O que acha? Bem mais simples, não?

Assim evitamos o retrabalho de sobrescrever uma única regra de CSS para um elemento específico e o código ficou bem mais legível. Dessa forma, enquanto estamos vendo esse último trecho de código conseguimos identificar mais facilmente o que ele faz em apenas uma única linha, sem precisar ler o restante do código e ver quais regras são sobrescritas.

:empty

Como o próprio nome sugere, a ideia desse seletor é aplicar um estilo em todos os elementos que não possuem um conteúdo (nós filhos dentro do DOM).

Vamos pensar na seguinte estrutura HTML:

<p class="empty"></p>
<p class="empty-with-pseudo"></p>
<p class="empty-with-space"> </p>
*:empty {
  background: red;
}

.empty-with-pseudo:before {
  content: 'conteudo inserido via CSS';
}

Nesse caso, somente o elemento .empty e o .empty-with-pseudo receberão o background vermelho.

Isso acontece porque o elemento .empty realmente está vazio e o .empty-with-pseudo, embora tenha um conteúdo inserido via CSS, não possui conteúdo algum inserido no HTML. Já o elemento .emtpy-with-space possui o espaço em branco como conteúdo.


Já conhecia esses seletores?

O que achou deles?

São bem simples mas acho que podem ajudar bastante a escrever um código mais legível e também a identificar qualquer elemento que possa ter passado esquecido ou esteja vazio sem querer (ou até mesmo para uma estilização específica) no seu código.