Vous utilisez @include vs @extend dans Sass?


93

Dans Sass, je ne peux pas vraiment discerner la différence entre l'utilisation @includeavec un mixin et l'utilisation @extendavec une classe d'espace réservé. Cela ne revient-il pas au même?


2
include ne vous donne pas d'étendre la classe de base, il ajoute simplement des options. Il vous suffit de vous conseiller de lire sass-lang.com/docs/yardoc/… et sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
CodeGroover

1
De plus, @CodeGroover, pas un commentaire utile du tout, vous avez peut-être mal compris la question. La lecture de ce donne des informations plus utiles: gist.github.com/antsa/970172
temporary_user_name

4
Chaque fois que vous utilisez un mixin sans paramètre, une extension sera plus efficace. Courtesy Chris
Abhijeet

Réponses:


87

Les extensions ne permettent pas la personnalisation, mais elles produisent un CSS très efficace.

%button
  background-color: lightgrey
  &:hover, &:active
    background-color: white

a
  @extend %button

button
  @extend %button

Résultat:

a, button {
  background-color: lightgrey;
}
a:hover, button:hover, a:active, button:active {
  background-color: white;
}

Avec les mixins, vous obtenez du CSS dupliqué, mais vous pouvez utiliser des arguments pour modifier le résultat pour chaque utilisation.

=button($main-color: lightgrey, $active-color: white)
  background-color: $main-color
  border: 1px solid black
  border-radius: 0.2em

  &:hover, &:active
    background-color: $active-color

a
  +button

button
  +button(pink, red)

Résulte en:

a {
  background-color: lightgrey;
  border: 1px solid black;
  border-radius: 0.2em;
}
a:hover, a:active {
  background-color: white;
}

button {
  background-color: pink;
  border: 1px solid black;
  border-radius: 0.2em;
}
button:hover, button:active {
  background-color: red;
}

Veuillez suivre cet ensemble consécutif d'exemples de code pour voir comment vous pouvez rendre votre code plus propre et plus maintenable en utilisant efficacement extend et mixins: http://thecodingdesigner.com/posts/balancing

Notez que SASS n'autorise malheureusement pas l'utilisation des extensions à l'intérieur des requêtes multimédias (et l'exemple correspondant du lien ci-dessus est faux). Dans le cas où vous devez étendre en fonction de requêtes multimédias, utilisez un mixin:

=active
  display: block
  background-color: pink

%active
  +active

#main-menu
  @extend %active // Active by default

#secondary-menu
  @media (min-width: 20em)
    +active // Active only on wide screens

Résultat:

#main-menu {
  display: block;
  background-color: pink;
}

@media (min-width: 20em) {
  #secondary-menu {
    display: block;
    background-color: pink;
  }
}

La duplication est inévitable dans ce cas, mais vous ne devriez pas trop vous en soucier car la compression gzip du serveur Web s'en chargera.

PS Notez que vous pouvez déclarer des classes d'espace réservé dans les requêtes multimédias.

Mise à jour 28/12/2014 : Extends produit des CSS plus compacts que les mixins , mais cet avantage est diminué lorsque CSS est gzippé. Si votre serveur utilise du CSS gzippé (il devrait vraiment!), Alors les extensions ne vous donnent presque aucun avantage. Vous pouvez donc toujours utiliser des mixins ! Plus d'informations à ce sujet ici: http://www.sitepoint.com/sass-extend-nobody-told-you/


2
Je ne pense pas que ce ne soit pas tout à fait exact ... vous pouvez personnaliser @extendsen remplaçant le parent d'extension. Bien sûr, vous ne pouvez pas passer d'arguments, mais alors est-ce la seule différence? Dans ce cas, est-ce @extendjuste @mixinsans arguments? Je ne vois toujours pas l'avantage ni la différence.
temporary_user_name

2
Voici quelques autres bizarreries ... stackoverflow.com/questions/30744625/…
Toni Leigh

Je serais prudent en interprétant l'aspect «ne vous donne presque aucun avantage» du dernier paragraphe, ici. La compression Gzip est un codeur Huffman basé sur un dictionnaire, donc si la répétition se produit assez loin l'un de l'autre, le texte ne sera pas présent dans le dictionnaire et les taux de compression en souffriront. Je préfère encore toujours @extendsi possible, car cela va produire CSS plus compact, qui encore compresser assez bien (il est texte ASCII, après tout).
amcgregor

@amcgregor, la différence est négligeable.
Andrey Mikhaylov - lolmaus

@ AndreyMikhaylov-lolmaus Je suis d'accord! Je m'attendrais à ce que la différence soit essentiellement incommensurable sur le fil, quel que soit le choix pour quoi que ce soit jusqu'à un mégaoctet ou plus de CSS généré, à part le fait que le résultat final non compressé en mémoire sera plus compact à l'aide @extend. Il s'agit d'une micro-optimisation apparemment basée sur l'intuition et les instincts, plutôt que sur la compréhension du fonctionnement réel du schéma de compression impliqué. (Aussi: il ignore la surcharge considérable du codage de transfert gzip à la demande; la compression n'est pas gratuite!;)
amcgregor

18

Une bonne approche consiste à utiliser les deux - créer un mixin qui vous permettra de nombreuses personnalisations, puis faire des extensions pour les configurations courantes de ce mixin. Par exemple (Syntaxe SCSS):

@mixin my-button($size: 15, $color: red) {
  @include inline-block;
  @include border-radius(5px);
  font-size: $size + px;
  background-color: $color;
}
%button {
  @include my-button;
}
%alt-button {
  @include my-button(15, green);
}
%big-button {
  @include my-button(25);
}

Cela vous évite d'appeler le mixin my-button encore et encore. Cela signifie également que vous n'avez pas à vous souvenir des paramètres des boutons communs, mais que vous avez toujours la possibilité de créer un bouton unique super unique si vous le souhaitez.

Je prends cet exemple d' un article de blog que j'ai écrit il n'y a pas longtemps. J'espère que cela t'aides.


12

À mon avis, les étendues sont un pur mal et doivent être évitées. Voici pourquoi:

étant donné le scss:

%mystyle {color: blue;}
.mystyle-class {@extend %mystyle}
//basically anything not understood by target browser (such as :last-child in IE8):
::-webkit-input-placeholder {@extend %mystyle}

Le CSS suivant sera généré:

.mystyle-class, ::-webkit-input-placeholder { //invalid in non-webkit browsers
  color: blue;
}

Lorsqu'un navigateur ne comprend pas un sélecteur, il invalide toute la ligne de sélecteurs. Cela signifie que votre précieuse classe mystyle n'est plus bleue (pour de nombreux navigateurs). Qu'est-ce que cela signifie vraiment? Si à tout moment vous utilisez une extension où un navigateur peut ne pas comprendre le sélecteur, toute autre utilisation de l'extension sera invalidée. Ce comportement permet également une imbrication maléfique:

%mystyle {color: blue;}
@mixin mystyle-mixin {@extend %mystyle; height: 0;}
::-webkit-input-placeholder {@include mystyle-mixin} 
//you thought nesting in a mixin would make it safe?
.mystyle-class {@extend %mystyle;}

Résultat:

::-webkit-input-placeholder, .mystyle-class { //invalid in non-webkit browsers
  color: blue;
}

::-webkit-input-placeholder {
  height: 0;
}

Tl; dr: @extend est tout à fait acceptable tant que vous ne l'utilisez jamais avec des sélecteurs spécifiques au navigateur. Si vous le faites, cela détruira soudainement les styles partout où vous l'avez utilisé. Essayez plutôt de vous fier aux mixins!


4
Note intéressante
simhumileco

4

Utilisez mixins s'il accepte un paramètre, où la sortie compilée changera en fonction de ce que vous lui passez.

@include opacity(0.1);

Utilisez extend (avec espace réservé) pour tous les blocs de styles statiques répétables.

color: blue;
font-weight: bold;
font-size: 2em;

0

Je suis totalement d'accord avec la réponse précédente de d4nyll. Il y a un texte sur l'option d'extension et pendant que je recherchais ce thème, j'ai trouvé beaucoup de plaintes concernant l'extension, alors gardez à l'esprit que et s'il y a une possibilité d'utiliser mixin au lieu d'étendre, ignorez simplement l'extension.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.