Um dos nossos recursos favoritos de pré-processador de CSS agora está integrado à linguagem: o aninhamento de regras de estilo.
Antes do aninhamento, cada seletor precisava ser declarado explicitamente, separadamente do se complementam. Isso leva à repetição, folha de estilo em massa e à criação esparsa. do usuário.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Após o aninhamento, os seletores podem ser regras de estilo contínuas e relacionadas a ele podem ser agrupadas.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Tente fazer isso no navegador.
A aninhamento ajuda os desenvolvedores porque reduz a necessidade de repetir seletores e também
co-localizar regras de estilo para elementos relacionados. Também pode ajudar os estilos a combinar
HTML segmentado. Se o componente .nesting
no exemplo anterior era
removido do projeto, você pode excluir todo o grupo em vez de pesquisar
para instâncias de seletores relacionadas.
A Transição pode ajudar com: - Organização - Redução do tamanho do arquivo - Refatoração
O aninhamento está disponível a partir do Chrome 112 e também para teste na Prévia técnica do Safari 162.
Começar a usar a Transição de CSS
Ao longo desta postagem,o sandbox de demonstração a seguir é usado para ajudar você visualizará as seleções. Neste estado padrão, nada é selecionado e tudo fica visível. Ao selecionar as várias formas e tamanhos, é possível praticar a sintaxe e vê-la em ação.
Dentro da sandbox há círculos, triângulos e quadrados. Algumas são pequenas e médias
ou grandes. Outras são azul, rosa ou roxo. Eles estão todos dentro do .demo
que contém o elemento. Esta é uma visualização dos elementos HTML que você
segmentação.
<div class="demo">
<div class="sm triangle pink"></div>
<div class="sm triangle blue"></div>
<div class="square blue"></div>
<div class="sm square pink"></div>
<div class="sm square blue"></div>
<div class="circle pink"></div>
…
</div>
Exemplos de aninhamento
O aninhamento de CSS permite definir estilos para um elemento dentro do contexto de outro seletor.
.parent {
color: blue;
.child {
color: red;
}
}
Neste exemplo, o seletor de classe .child
está aninhado
o seletor de classe .parent
. Isso significa que o seletor .child
aninhado
só se aplicam a elementos filhos de elementos com uma classe .parent
.
Este exemplo poderia ser escrito usando o símbolo &
, para explicitamente
indicam onde a classe pai deve ser colocada.
.parent {
color: blue;
& .child {
color: red;
}
}
Esses dois exemplos são funcionalmente equivalentes, e você tem opções à medida que exemplos mais avançados são explorados neste artigo.
Seleção dos círculos
Para este primeiro exemplo, a tarefa é adicionar estilos para esmaecer e desfocar apenas o círculos na demonstração.
Sem aninhamento, CSS atual:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Com o aninhamento, há duas maneiras válidas:
/* & is explicitly placed in front of .circle */
.demo {
& .circle {
opacity: .25;
filter: blur(25px);
}
}
ou
/* & + " " space is added for you */
.demo {
.circle {
opacity: .25;
filter: blur(25px);
}
}
O resultado: todos os elementos dentro de .demo
com uma classe .circle
são
desfocados e quase invisível:
Selecionando triângulos e quadrados
Essa tarefa requer a seleção de vários elementos aninhados, também chamado de seletor de grupo.
Sem aninhamento, o CSS atual oferece duas maneiras:
.demo .triangle,
.demo .square {
opacity: .25;
filter: blur(25px);
}
ou usando :is()
/* grouped with :is() */
.demo :is(.triangle, .square) {
opacity: .25;
filter: blur(25px);
}
Com o aninhamento, há duas maneiras válidas:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
ou
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Como resultado, apenas os elementos .circle
permanecem dentro de .demo
:
Seleção de triângulos e círculos grandes
Essa tarefa requer um seletor composto, em que elementos devem ter as duas classes presentes para serem selecionados.
Sem aninhamento, CSS atual:
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
ou
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
Com o aninhamento, há duas maneiras válidas:
.demo {
.lg.triangle,
.lg.circle {
opacity: .25;
filter: blur(25px);
}
}
ou
.demo {
.lg {
&.triangle,
&.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Como resultado, todos os triângulos e círculos grandes estão escondidos dentro de .demo
:
Dica profissional com seletores compostos e aninhamento
O símbolo &
é seu amigo aqui, já que mostra explicitamente como adicionar elementos aninhados
seletores. Veja o exemplo a seguir:
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Embora seja uma maneira válida de aninhar, os resultados não corresponderão aos elementos esperados.
O motivo é que, sem &
para especificar o resultado desejado de .lg.triangle,
.lg.circle
combinado, o resultado real seria .lg .triangle, .lg
.circle
. seletores descendentes.
Selecionar todas as formas exceto as rosas
Essa tarefa requer uma pseudoclasse funcional de negação, em que os elementos não podem têm o seletor especificado.
Sem aninhamento, CSS atual:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Com o aninhamento, há duas maneiras válidas:
.demo {
:not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
ou
.demo {
& :not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
O resultado, todas as formas que não são rosa ficam ocultas dentro de .demo
:
Precisão e flexibilidade com o &
Digamos que você queira segmentar .demo
com o seletor :not()
. &
é obrigatório para
que:
.demo {
&:not() {
...
}
}
Isso compõe .demo
e :not()
em .demo:not()
, em oposição ao anterior
que precisava de .demo :not()
. Esse lembrete é muito importante quando
para aninhar uma interação :hover
.
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
Mais exemplos de aninhamento
A especificação CSS para aninhamento é com mais exemplos. Para saber mais sobre a sintaxe por meio de exemplos, ela abrange uma ampla gama de exemplos válidos e inválidos.
Os próximos exemplos apresentarão brevemente um recurso de aninhamento de CSS, para que você entender a amplitude de funções que ela introduz.
Transição de @media
Pode ser uma distração se mover para uma área diferente da folha de estilo para encontrar condições da consulta de mídia que modificam um seletor e seus estilos. Essa distração não é mais possível aninhar as condições dentro do contexto.
Para facilitar a sintaxe, se a consulta de mídia aninhada só modificar os estilos para o contexto do seletor atual, uma sintaxe mínima pode ser usada.
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
O uso explícito de &
também pode ser utilizado:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
Este exemplo mostra a sintaxe expandida com &
, além de segmentar .large
para demonstrar outros recursos de aninhamento continuam funcionando.
Saiba mais sobre o aninhamento de @rules.
Aninhamento em qualquer lugar
Todos os exemplos até aqui continuaram ou foram anexados a um contexto anterior. É possível mudar ou reorganizar completamente o contexto, se necessário.
.card {
.featured & {
/* .featured .card */
}
}
O símbolo &
representa uma referência a um objeto seletor (não uma string) e
pode ser colocado em qualquer lugar de um seletor aninhado. Ele pode até mesmo ser colocado
horários:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
Esse exemplo é um pouco inútil, mas certamente há cenários em que de repetir um contexto de seletor é útil.
Exemplos de aninhamento inválidos
Alguns cenários de sintaxe de aninhamento são inválidos e podem surpreender você caso você tenha feito o aninhamento em pré-processadores.
Aninhamento e concatenação
Muitas convenções de nomenclatura de classes CSS contam que o aninhamento pode concatenar ou anexam seletores como se fossem strings. Isso não funciona no aninhamento de CSS, os seletores não são strings, são referências de objetos.
.card {
&--header {
/* is not equal to ".card--header" */
}
}
Uma explicação mais detalhada pode ser encontrada na especificação.
Exemplo complicado de aninhamento
Aninhamento nas listas de seletores e :is()
Considere o seguinte bloco CSS de aninhamento:
.one, #two {
.three {
/* some styles */
}
}
Esse é o primeiro exemplo que começa com uma lista de seletores e continua a aninhamento. Os exemplos anteriores tinham terminado apenas com uma lista de seletores. Não há nada inválido neste exemplo de aninhamento, mas há um detalhe de implementação potencialmente complicado sobre o aninhamento dentro de listas de seletores, especialmente aqueles que incluem um seletor de ID.
Para que o intent do aninhamento funcione, qualquer lista de seletores que não for o aninhamento mais interno será unida a :is()
pelo navegador. Esse ajuste mantém o agrupamento da lista de seletores em qualquer contexto criado. O efeito colateral desse agrupamento, :is(.one, #two)
, é que ele adota a especificidade da pontuação mais alta nos seletores entre parênteses. É assim que :is()
sempre funciona, mas pode ser uma surpresa ao usar a sintaxe de aninhamento, porque não é exatamente o que foi criado. O truque em resumo: o aninhamento com IDs e listas de seletores pode levar a seletores de especificidade muito alta.
Para recapitular claramente o exemplo complicado, o bloco de aninhamento anterior será aplicado ao documento desta forma:
:is(.one, #two) .three {
/* some styles */
}
Fique atento ou ensine os lints a avisarem quando você fizer o aninhamento dentro de uma lista de seletores que usa um seletor de ID. A especificidade de todo o aninhamento nessa lista de seletores será alta.
Como combinar aninhamento e declarações
Considere o seguinte bloco CSS de aninhamento:
.card {
color: green;
& { color: blue; }
color: red;
}
A cor dos elementos .card
será blue
.
Todas as declarações de estilo misturado são elevadas para a parte superior, como se fossem criados antes da ocorrência de qualquer aninhamento. Confira mais detalhes nas especificações.
Existem maneiras de evitar isso. Confira abaixo os três estilos de cores em &
, que
mantém a ordem em cascata conforme a intenção do autor. A cor do
.card
elementos serão vermelhos.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
Na verdade, é recomendável unir todos os estilos que seguem o aninhamento com uma &
.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Detecção de recursos
Há duas ótimas maneiras de detectar o aninhamento de CSS: usar aninhamento
@supports
para verificar o recurso de análise do seletor de aninhamento.
Como usar o aninhamento:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
Utilizando @supports
:
@supports (selector(&)) {
/* nesting parsing available */
}
Bramus (link em inglês) tem um ótimo Codepen que mostra essa estratégia.
Como depurar com o Chrome DevTools
O suporte atual para aninhamento no DevTools é mínimo. Atualmente, você encontra Os estilos são representados no painel Styles como esperado, mas rastrear o aninhamento e o contexto completo do seletor ainda não é suportado. Temos um design e planos para deixar isso transparente e claro.
O Chrome 113 planeja ter mais suporte para o aninhamento de CSS. Fique por dentro das novidades.
O futuro
A Transição de CSS está somente na versão 1. A versão 2 introduz mais facilidade sintática e possivelmente menos regras para memorizar. Há muita demanda para que a análise do aninhamento não seja limitada ou momentos complexos.
A Transição é uma grande melhoria na linguagem CSS. Tem implicações na criação a quase todos os aspectos arquitetônicos dos CSS. Esse grande impacto precisa ser profundamente exploradas e compreendidas antes da versão 2 ser efetivamente especificada.
Para finalizar, confira uma demonstração
que usa @scope
, aninhamento e @layer
juntos. É tudo muito emocionante!