Sass .scss: imbrication et classes multiples?

332

J'utilise Sass (.scss) pour mon projet actuel.

Exemple suivant:

HTML

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

SCSS

.container {
    background:red;
    color:white;

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

Cela fonctionne très bien.

Puis-je gérer plusieurs classes tout en utilisant des styles imbriqués.

Dans l'exemple ci-dessus, je parle de ceci:

CSS

.container.desc {
    background:blue;
}

Dans ce cas, tout div.containerserait normalement redmais div.container.descserait bleu.

Comment puis-je imbriquer cela à l'intérieur containeravec Sass?

mat
la source
1
Vous devez utiliser un sélecteur de classe double. Ce problème est un exemple parfait d'option d'imbrication dans Sass. Vous pouvez tout lire ici kolosek.com/nesting-in-less-and-sass
Nesha Zoric

Réponses:

571

Vous pouvez utiliser la référence du sélecteur parent & , elle sera remplacée par le sélecteur parent après la compilation:

Pour votre exemple:

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

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

Le &sera complètement résolu, donc si votre sélecteur parent est lui-même imbriqué, l'imbrication sera résolue avant de remplacer le &.

Cette notation est le plus souvent utilisée pour écrire des pseudo-éléments et des classes :

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

Cependant, vous pouvez placer le &à pratiquement n'importe quelle position que vous aimez * , donc ce qui suit est également possible:

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

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

Cependant, sachez que cela casse en quelque sorte votre structure d'imbrication et peut donc augmenter l'effort de recherche d'une règle spécifique dans votre feuille de style.

*: Aucun autre personnage que les espaces blancs n'est autorisé devant le &. Donc, vous ne pouvez pas faire une concaténation directe de selector+ &- #id&jetterait une erreur.

Christoph
la source
12
Juste une remarque, une utilisation courante de &est lors de l'utilisation de pseudo-éléments et pseudo-classes. Par exemple: &:hover.
écraser
1
@crush Par souci d'exhaustivité, j'ai ajouté ceci à ma réponse. Merci pour le commentaire.
Christoph
1
Merci. Je pensais que j'étais stupide car cela n'est pas mentionné dans le guide des bases! BTW the docs a déplacé l'URL vers: sass-lang.com/documentation/…
scipilot
1
Si &est utilisé à la fin d'une ligne, il place cette ligne au début du reste des classes à tous les autres niveaux. Vous pouvez combiner des éléments en faisant &.descsous .container, ce qui y ajouterait .desc, résultant en.container.desc
Kate Miller
scss-lint suggère d'utiliser "& :: hover" (double colones)
Marcel Lange
18

Si tel est le cas, je pense que vous devez utiliser une meilleure façon de créer un nom de classe ou une convention de nom de classe. Par exemple, comme vous l'avez dit, vous voulez que la .containerclasse ait une couleur différente en fonction d'une utilisation ou d'une apparence spécifique. Tu peux le faire:

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;
}

Le code ci-dessus est basé sur la méthodologie BEM dans les conventions de dénomination des classes. Vous pouvez vérifier ce lien: BEM - Méthodologie de modification des éléments de bloc

Murdock Helscream
la source
remarquez que cela semble agréable, mais devrait être évité à tout prix. vous me remercierez à l'avenir lorsque vous essaierez de rechercher votre projet .container--descet de vous retrouver sans résultat.
Stavm
2

La réponse de Christoph est parfaite. Parfois, cependant, vous voudrez peut-être monter plus d'un cours. Dans ce cas, vous pouvez essayer les fonctionnalités @at-rootet #{}css qui permettraient à deux classes racine de s'asseoir côte à côte en utilisant &.

Cela ne fonctionnerait pas (en raison de la nothing before &règle):

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

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

Mais cela (en utilisant @at-root plus #{&}):

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

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

user2299879
la source