J'utilise le port SASS de Bootstrap , et je me demande s'il y a une différence entre l'utilisation des mixins prédéfinis et l'utilisation de @extend
.
Par exemple, si j'ai:
<div class="wrapper">
Some content here....
</div>
Y a-t-il une différence entre faire
.wrapper {
@include make-row();
}
et
.wrapper {
@extend .row;
}
?
S'il n'y a pas de différence, existe-t-il d'autres mixins qui ne sont pas équivalents à un seul @extend
déclaration? S'il n'y a pas de tels mixins, pourquoi les mixins existent-ils même?
La grande différence entre @extend
et un mixin est la façon dont le css est compilé. Cela ne ressemble pas beaucoup à des exemples simples, mais les différences et les implications sont importantes et peuvent être un véritable casse-tête dans la nature si elles sont utilisées avec négligence. @extend
est un peu comme de l'or fou, a l'air bien au début, mais ...
Regardons un exemple simple:
@ extend
.row {
width: 50px;
}
.new-row {
@extend .row;
}
.another-row {
@extend .row;
}
se compile en:
.row,
.new-row,
.another-row {
width: 50px;
}
mixin
@mixin row() {
width: 50px;
}
.new-row {
@include row();
}
.another-row {
@include row();
}
se compile en:
.new-row {
width: 50px;
}
.another-row {
width: 50px;
}
Un mixin inclut les propriétés partout où il est touché - en les copiant à chaque fois - alors qu'un @extend
regroupe les sélecteurs et définit les propriétés une fois. Ce n'est pas immédiatement évident, car la différence est dans le CSS compilé mais cela a des implications importantes:
Ordre de chargement
Avec @extend
les sélecteurs seront regroupés au premier point du sass où ils sont rencontrés, ce qui peut conduire à un dépassement étrange. Si vous définissez un sélecteur et utilisez @extend
pour importer une propriété et essayer de remplacer une propriété définie précédemment dans votre sass, mais après le point auquel les propriétés étendues sont regroupées dans le CSS, la substitution ne fonctionnera pas. Cela peut être assez déroutant.
Considérez cet ensemble logiquement ordonné de définitions css et le HTML probable: <div class='row highlight-row'></div>
:
.red-text {
color: red;
}
.row {
color: green;
}
.highlight-row {
@extend .red-text;
}
se compile en:
.red-text,
.highlight-row {
color: red;
}
.row {
color: green;
}
Donc, même si l'ordre des sass donne l'impression que la couleur de la ligne serait rouge, le CSS compilé le rendra vert
Groupements pauvres
@extend
peut entraîner des sélecteurs mal regroupés dans le CSS résultant. Vous pouvez vous retrouver avec trente ou quarante choses indépendantes partageant toutes la même propriété par exemple. En utilisant @extend
pour les polices en est un bon exemple.
Imbrication
Si vous utilisez sass profondément imbriqué (ce qui n'est pas bon, btw) et que vous utilisez @extend
vous dupliquerez le sélecteur entièrement imbriqué pour chaque @extend
vous utilisez, ce qui entraîne des css gonflés. Je l'ai souvent vu:
.selector-1 .selector-2 .selector-3 .selector-4,
.selector-1 .selector-2 .selector-3 .selector-4 a,
.selector-1 .selector-2 .selector-3 .selector-4 li,
.selector-1 .selector-2 .selector-3 .selector-4 td {
font-family: ariel;
}
Si vous êtes nouveau dans SASS, il est utile de regarder les CSS compilés.
Requêtes médias
@extend
ne fonctionne pas dans les requêtes multimédias, car les requêtes multimédias ne sont pas des sélecteurs.
Conclusion
Ma règle d'or consiste à utiliser un @extend
sur un mixin si vous n'avez pas de paramètres et si vous pouvez raisonnablement définir @extend et le partager entre quelques sélecteurs étroitement liés qui existent à proximité dans le sass, par exemple, dans le même fichier qui définit un module sass. Les boutons sont un bon exemple de @extend bien utilisé:
%button {
padding: 10px;
}
.call-to-action {
@extend %button;
background-color: $green;
}
.submit {
@extend %button;
background-color: $grey;
}
Le meilleur article pour aider à faire le choix est ici
PS, le %
le signe est une utilisation de l'espace réservé s'étend