Aninhamento no Sass: o &, BEM e o limite de três níveis
O que o aninhamento vira no CSS final, como o & monta seletores BEM e quanto peso um componente aninhado fundo custa de verdade.
Aninhamento coloca regras relacionadas dentro do mesmo bloco no arquivo SCSS. Ele melhora a leitura quando expressa a estrutura de um componente, mas pode esconder um seletor longo. O navegador não recebe “níveis”: o Sass combina cada parte e grava seletores CSS completos.
Por isso, nesta aula toda entrada aparece ao lado da saída do Dart Sass 1.103.1. Não julgue o aninhamento apenas pela beleza do fonte; julgue pelo seletor que ele produz e pela dependência criada com o HTML.
npx sass --stdin --no-source-map --style=expandedEsse comando não imprime uma mensagem de sucesso: nos casos válidos, o stdout
é o próprio CSS compilado, reproduzido em cada bloco abaixo.
Antes de seguir, revise seletores e cascata. Aninhar não reduz especificidade e não transforma uma classe descendente em componente isolado.
O aninhamento mais simples vira um descendente
Uma regra escrita dentro de outra, sem &, vira uma relação de descendência:
.card {
.title { color: #111827; }
}Isso seleciona qualquer .title dentro de .card, mesmo vários níveis abaixo.
Não significa “filho direto”. Se essa era a intenção, escreva > .title. A
indentação do SCSS não descreve a profundidade real do DOM.
O & aponta para o seletor pai
Pseudo-classes não devem ganhar um espaço antes delas. O & é substituído por
.button e cola :hover ou :focus-visible ao seletor:
.button {
&:hover { transform: translateY(-2px); }
&:focus-visible { outline: 3px solid #a78bfa; }
}Sem &, .button :hover procuraria um descendente em estado hover. É outro
seletor e frequentemente parece funcionar por acidente quando o botão contém
um ícone.
BEM com sufixo: &__element e &--modifier
Quando o seletor pai termina em nome alfanumérico, Sass permite anexar um sufixo. Isso combina bem com BEM:
.card {
&__title { font-weight: 700; }
&--featured { border-color: #6d28d9; }
}Note que .card__title não é descendente de .card; é uma classe independente
com nome derivado. A proximidade no SCSS é organização de autoria, não uma
exigência de colocar as duas classes no mesmo elemento.
Colocar o contexto antes do componente
O & também pode aparecer depois de um seletor de contexto. Aqui a regra vale
quando um ancestral ativa tema escuro:
.card {
[data-theme="dark"] & {
background: #111827;
}
}Esse padrão é útil, mas uma custom property costuma escalar melhor para muitas cores de tema. A lição de variáveis no Sass explica por que valores que mudam no DOM pertencem ao CSS.
Filhos e irmãos sem ambiguidade
Combinadores podem iniciar a regra interna. O compilador liga o combinador ao
pai mesmo sem & explícito:
.card {
> .title { margin: 0; }
+ .card { margin-top: 1rem; }
}O primeiro caso exige filho direto; o segundo seleciona um card imediatamente depois de outro. São relações intencionais. Aninhar cada detalhe só porque ele aparece dentro do componente no HTML não é intencional — é acoplamento.
O limite de três níveis é uma proteção, não sintaxe
O Sass compila quatro níveis sem reclamar:
.page {
.sidebar {
.card {
.title { color: #6d28d9; }
}
}
}O resultado tem especificidade 0-4-0: quatro classes. Uma simples classe de
utilidade, 0-1-0, não vence na mesma origem e camada, mesmo quando aparece
depois; a especificidade maior é comparada antes da ordem de declaração.
Mais importante, mover o card para fora de .sidebar quebra a regra visual.
Use três níveis como alarme: componente, elemento e estado já ocupam o orçamento.
Se precisar de um quarto, tente nomear a parte com uma classe própria. A aula de
especificidade CSS ajuda a calcular o peso sem
recorrer a !important.
Esse limite também melhora a remoção de código. Quando cada parte tem uma classe
estável, buscar .card__title mostra onde ela nasce e onde é usada. Um seletor
formado pela árvore inteira pode continuar no CSS depois que o HTML mudou, sem
corresponder a nada. A folha cresce e ninguém se sente seguro para apagar. Um
seletor curto é, portanto, uma ferramenta de manutenção, não apenas preferência
de estilo.
O erro de posição do &
Como o pai pode ser um seletor de tipo, Sass só aceita & no começo de um
seletor composto. Tentar colocar span antes dele falha:
.card {
span& { color: red; }
}A correção depende da intenção. Para “um span que também tem .card”, use
span.card fora do bloco; para “um span dentro do card”, use span aninhado.
Não troque a ordem até o compilador aceitar sem entender o seletor resultante.
Sass nesting e CSS nesting nativo
CSS moderno também aceita regras aninhadas. Para pseudo-classes, esta escrita é familiar e não requer compilação em navegadores compatíveis:
.button {
&:hover {
transform: translateY(-2px);
}
}No CSS nativo, a regra permanece aninhada no arquivo entregue; quando a mesma
entrada passa pelo Sass, ela vira .button:hover.
A concatenação BEM &__title é o ponto que impede uma troca mecânica: nesting
nativo não é um gerador geral de texto de seletor. Antes de remover Sass de um
projeto, procure sufixos, mixins, maps e funções — não apenas blocos indentados.
Checklist antes de aceitar um seletor aninhado
Leia o CSS compilado e responda: o seletor tem no máximo três classes? O
componente funciona se mudar de página? O estado usa & sem espaço? A relação
de filho ou irmão é realmente parte do contrato? Se qualquer resposta for não,
achate a regra.
.card {}
.card__title {}
.card:hover {}Na contagem de especificidade, .card e .card__title têm 0-1-0;
.card:hover tem 0-2-0.
O próximo passo é reutilizar declarações com mixins. O guia completo de Sass mantém o mapa da trilha e mostra quando o CSS nativo já é suficiente.
Perguntas frequentes
Qual é o limite técnico de aninhamento no Sass?
O & sempre significa a classe externa?
Nesting do CSS nativo é igual ao do Sass?
Dúvidas e comentários
Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.
Entrar para perguntarÉ o mesmo login gratuito dos cursos.
Nenhuma dúvida por aqui ainda — a primeira pode ser a sua.
Todo o código deste artigo foi executado em Dart Sass 1.103.1 (dart2js 3.13.1), Node 26.3.0, macOS, e as saídas exibidas são as reais — como produzimos este conteúdo.
Fontes consultadas
- Sass — Parent Selector — sass-lang.com
- Sass — Style Rules — sass-lang.com
- MDN — CSS nesting — developer.mozilla.org


