CSS nesting

Introdução

CSS Nesting traz para o CSS nativo uma sintaxe de aninhamento de seletores que muitos já conheciam de pré-processadores. A diferença é que agora o recurso é parte do CSS, com regras próprias de interpretação e impacto direto em cascata, especificidade e manutenibilidade.

Neste tutorial você vai aprender quando usar nesting, como evitar armadilhas comuns, especialmente com &, e como aplicar o recurso com foco em CSS estrutural, semântico e durável, sem transformar o stylesheet em um “labirinto” difícil de manter.

O que é CSS nesting e o que ele não é

CSS nesting permite escrever regras relacionadas dentro do mesmo bloco, reduzindo repetição de seletores e melhorando a leitura quando há hierarquia real no componente.

  • Use nesting para encapsular variações e estados do mesmo componente.
  • Evite nesting para “espelhar a árvore DOM” inteira. Isso degrada a manutenção.

O caso mais simples é aninhar um seletor “filho” dentro de um “pai”.

CSS
.card {
  padding: 1rem;
  border: 1px solid #ccc;

  .card__title {
    font-weight: 700;
  }

  .card__content {
  color: #333;
  }
}

Tudo dentro de .card { ... } estiliza elementos (seletores) no contexto do componente. Prefira nesting para partes do componente (ex.: .card__title) e para estados/variantes (ex.: &:hover, &--modifier).

Evite nesting que cria cadeias longas de descendentes (ex.: .card .card__content .text .highlight { ... }), pois isso aumenta a especificidade e dificulta manutenção.

Mantenha a profundidade baixa (idealmente 1 ou 2 níveis)

O papel do &: estados, variantes e composição

O & representa o seletor do bloco “pai” (o seletor atual), e é essencial para escrever estados e modificadores conforme os exemplos a seguir:

Exemplo 1
CSS - estados
.button {
  padding: .75rem 1rem;

  &:hover {
  filter: brightness(0.95);
  }

  &:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
  }
}

No Exemplo 1 o & representa o seletor do bloco pai que é .button. Assim &:hover e &:focus-visible lê-se .button:hover e .button:focus-visible que estilizam o botão em estados de interação. Isso mantém a relação clara entre o componente e seus estados, facilitando a leitura e manutenção.

Exemplo 2
CSS - modificadores
.button {
  background: #111;
  color: #fff;
  
  &--danger {
    background: #b00020;
  }
}

No Exemplo 2 o bloco define o estilo base da classe .button (fundo #111 e texto #fff) e, com CSS nesting, cria uma variação usando &--danger, onde o & representa .button. Na prática, isso gera o seletor .button--danger, que sobrescreve apenas o background para #b00020, mantendo o restante do estilo herdado/compartilhado da base.

Exemplo 3
CSS - modificadores
.card {
  border-radius: .5rem;

  .theme-dark & {
    border-color: #444;
    background: #111;
    color: #eee;
    }
}

No Exemplo 3, o componente muda quando está dentro de um container específico. Quando .card estiver dentro de .theme-dark, aplique estes estilos.

Especificidade e cascata

Cuidado: Por que nesting pode te “enganar” aumentando a especificidade sem você perceber. .card__title { ... } é uma coisa
.card .card__title { ... } é mais específico

Exemplo
CSS - especificidade
/* menos específico */
  .card__title { color: #222; }

  /* mais específico (por estar aninhado como descendente) */
  .card {
  .card__title { color: #111; }
  }

Implicação prática você pode começar a “precisar” de seletores cada vez mais fortes para sobrescrever estilos, e isso corrói a durabilidade do CSS.

Estratégia segura: Aninhe estados/variantes (&:hover, &--x, .ctx &). Evite nesting que vira cadeia longa de descendentes.

Padrão recomendado: Use nesting para “comportamento”, não para “estrutura”.

Nesting em projetos grandes

Bloco do componente define base, nesting define estados, variantes, contextos.

Partes do componente (sub-elementos) podem ser aninhados, mas com cautela.

Exemplo
CSS
.alert {
  padding: 1rem;
  border-radius: .5rem;

  &__title {
  font-weight: 700;
  }

  &__text {
  margin-top: .25rem;
  }

  &--warning {
  background: #fff8e1;
  }

  &--error {
  background: #ffebee;
  }

  .theme-dark & {
  background: #111;
  color: #eee;
  }
}

Se você entendeu os exemplos mostrados esse padrão de código é auto explicativo. Ele tende a gerar um CSS semântico, previsível e com baixo custo de manutenção.

Boas práticas de CSS nesting

Limite a profundidade: nesting profundo geralmente é sinal de arquitetura frágil.

Prefira nomes semânticos: estados e variantes devem comunicar intenção (ex.: --danger, --muted).

Evite depender do DOM: se mudar o HTML quebrar estilos em cascata, o CSS não está durável.

Use linters: configure regras contra profundidade excessiva e seletores muito específicos.

Anti-padrões comuns com CSS nesting

Aninhar 4 ou mais níveis, vira “Sass ruim” em CSS nativo.

Aninhar só por estética (sem ganho real de manutenção).

Criar seletores descendentes longos para “ganhar” na especificidade.

Misturar responsabilidades (layout global dentro do componente e vice-versa).

Regra prática se você está aninhando para “corrigir” conflitos, o problema é a arquitetura, não a sintaxe.

Conclusão

CSS nesting é um recurso que pode aumentar muito a clareza e a durabilidade do seu CSS quando usado para expressar estados, variantes e contextos do componente. O ganho real vem de manter o aninhamento raso, evitar cadeias de descendência e proteger a arquitetura contra escalada de especificidade. Se este tutorial te ajudou, compartilhe com quem trabalha com CSS em projetos grandes e confira outros tutoriais avançados no Site do Maujor.

Compartilhe essa matéria com seus amigos

logo twitter logo facebook logo linkedin

Conheça os livros do Maujor®

Visite o site dos livros do Maujor.

Os sites do Maujor estão hospedados na DialHost.