Utiliser @include vs @extend dans Sass?

Dans Sass, Je ne peux pas tout à fait discerner la différence entre l'utilisation de @include avec un mixin et l'utilisation de @extend avec une classe d'espace réservé. N'ont-ils pas le montant à la même chose?

78
demandé sur Aerovistae 2013-08-02 08:16:40

5 réponses

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

%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 mixins, vous obtenez des CSS dupliqués, 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ésultats dans:

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 extends et mixins efficacement: http://thecodingdesigner.com/journal/balancing-ideal-sass-and-ideal-css

Notez que Sass n'autorise malheureusement pas l'utilisation de requêtes extends inside media (et l'exemple correspondant du lien ci-dessus est erroné). Dans la situation où vous devez étendre en fonction des requêtes de mé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 prendra en charge il.

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

Mise à jour 2014-12-28: Extends produit des CSS plus compacts que mixins , mais cet avantage est diminué lorsque CSS est gzippé. Si votre serveur sert CSS gzippé(il devrait vraiment!), alors étend vous donner presque aucun avantage. Vous pouvez donc toujours utilisermixins ! En savoir plus ici: http://www.sitepoint.com/sass-extend-nobody-told-you/

72
répondu lolmaus - Andrey Mikhaylov 2016-08-26 13:01:54

Une bonne approche consiste à utiliser les deux - créer un mixin qui vous permettra beaucoup de personnalisation, puis faire des extensions pour les configurations communes 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 vous avez toujours la possibilité de créer un bouton unique et unique si vous choisissez.

Je prends cet exemple de un blog que j'ai écrit il n'ya pas longtemps. Espérons que cette aide.

14
répondu FreddyBushBoy 2014-02-23 12:39:08

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

Compte tenu du 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? Si à tout moment vous utilisez une extension où un navigateur peut ne pas comprendre le sélecteur toute autre utilisation de l'extension sera être invalidé. 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 parfaitement correct tant que vous ne l'utilisez jamais avec des sélecteurs spesific de navigateur. Si vous le faites, il va soudainement démolir les styles partout où vous l'avez utilisé. Essayez de compter sur mixins à la place!

8
répondu clearfix 2015-12-22 11:09:37

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

@include opacity(0.1);

Utiliser étendre (avec espace réservé) pour tout statique reproductible blocs de styles.

color: blue;
font-weight: bold;
font-size: 2em;
3
répondu d4nyll 2015-02-16 09:11:14

Je suis totalement d'accord avec la réponse précédente de d4nyll. Il y a un texte à propos de l'option extend et pendant que je faisais des recherches sur ce thème, j'ai trouvé beaucoup de plaintes à propos de extend, alors gardez à l'esprit que et s'il y a une possibilité d'utiliser mixin au lieu de extend, il suffit de sauter extend.

0
répondu Nesha Zoric 2018-03-13 10:52:11