Sass .scss: aninhamento e várias classes?

332

Estou usando o Sass (.scss) para o meu projeto atual.

Exemplo a seguir:

HTML

<div class="container desc">
    <div class="hello">
        Hello World
    </div>
</div>

SCSS

.container {
    background:red;
    color:white;

    .hello {
        padding-left:50px;
    }
}

Isso funciona muito bem.

Posso lidar com várias classes enquanto estiver usando estilos aninhados.

No exemplo acima, estou falando sobre isso:

CSS

.container.desc {
    background:blue;
}

Nesse caso, tudo div.containerseria normalmente, redmas div.container.descseria azul.

Como posso aninhar isso por dentro containercom Sass?

mate
fonte
1
Você deve usar um seletor de classe dupla. Esse problema é um exemplo perfeito de opção de aninhamento no Sass. Você pode ler tudo sobre isso aqui kolosek.com/nesting-in-less-and-sass
Nesha Zoric

Respostas:

570

Você pode usar a referência do seletor pai & , que será substituída pelo seletor pai após a compilação:

Para o seu exemplo:

.container {
    background:red;
    &.desc{
       background:blue;
    }
}

/* compiles to: */
.container {
    background: red;
}
.container.desc {
    background: blue;
}

O &resolverá completamente, portanto, se o seletor pai estiver aninhado, o aninhamento será resolvido antes de substituir o &.

Essa notação é mais frequentemente usada para escrever pseudoelementos e -classes :

.element{
    &:hover{ ... }
    &:nth-child(1){ ... }
}

No entanto, você pode colocá-lo &em praticamente qualquer posição que desejar * , para que também seja possível o seguinte:

.container {
    background:red;
    #id &{
       background:blue;
    }
}

/* compiles to: */
.container {
    background: red;
}
#id .container {
    background: blue;
}

No entanto, esteja ciente de que isso de alguma forma interrompe sua estrutura de aninhamento e, portanto, pode aumentar o esforço de encontrar uma regra específica na sua folha de estilo.

*: Nenhum outro caractere além de espaços em branco é permitido na frente do &. Portanto, você não pode fazer uma concatenação direta de selector+ &- #id&geraria um erro.

Christoph
fonte
12
Apenas uma observação, um uso comum de &é ao usar pseudo-elementos e pseudo-classes. Por exemplo: &:hover.
esmagar
1
@crush Por uma questão de completude, adicionei isso à minha resposta. Obrigado pelo comentário.
Christoph
1
Obrigado. Eu pensei que estava sendo estúpido, pois não é mencionado no guia básico! Entre os documentos movidos URL para: sass-lang.com/documentation/…
scipilot
1
Se &for usado no final de uma linha, ela será colocada no início do restante das classes em todos os outros níveis. Você pode combinar elementos, fazendo &.descsob .container, o que acrescentar .Desc a ele, resultando em.container.desc
Kate Miller
SCSS fiapos sugere a utilização "& :: hover" (colones duplas)
Marcel Lange
18

Se for esse o caso, acho que você precisa usar uma maneira melhor de criar um nome de classe ou uma convenção de nome de classe. Por exemplo, como você disse que deseja que a .containerclasse tenha cores diferentes de acordo com um uso ou aparência específica. Você consegue fazer isso:

SCSS

.container {
  background: red;

  &--desc {
    background: blue;
  }

  // or you can do a more specific name
  &--blue {
    background: blue;
  }

  &--red {
    background: red;
  }
}

CSS

.container {
  background: red;
}

.container--desc {
  background: blue;
}

.container--blue {
  background: blue;
}

.container--red {
  background: red;
}

O código acima é baseado na metodologia BEM nas convenções de nomenclatura de classes. Você pode verificar este link: BEM - Metodologia de Modificador de Elemento de Bloco

Murdock Helscream
fonte
observe que isso soa bem, mas deve ser evitado a todo custo. você me agradecerá no futuro quando tentar pesquisar seu projeto .container--desce acabar sem resultados.
Stavm 19/12/19
2

A resposta de Christoph é perfeita. Às vezes, porém, você pode querer ter mais aulas do que uma. Nesse caso, você pode tentar os recursos @at-roote #{}css que permitiriam que duas classes raiz se sentassem próximas uma da outra usando &.

Isso não funcionaria (devido à nothing before &regra):

container {
    background:red;
    color:white;
    
    .desc& {
      background: blue;
    }

    .hello {
        padding-left:50px;
    }
}

Mas isso seria (usando @at-root plus #{&}):

container {
    background:red;
    color:white;
    
    @at-root .desc#{&} {
      background: blue;
    }

    .hello {
        padding-left:50px;
    }
}

user2299879
fonte