web-dev-qa-db-fra.com

Utiliser @include vs @extend dans Sass?

Dans Sass, je ne vois pas très bien la différence entre utiliser @include avec un mixin et utiliser @extend avec une classe d'espace réservé. Ne sont-ils pas la même chose?

82

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

Suivez cet ensemble consécutif d’exemples de code pour voir comment rendre votre code plus propre et plus facile à gérer en utilisant efficacement les extensions et les mixines: http://thecodingdesigner.com/journal/balancing-ideal-sass-and-ideal-css

Notez que SASS n'autorise malheureusement pas l'utilisation des requêtes étendues à l'intérieur des médias (et l'exemple correspondant à partir du lien ci-dessus est faux). Dans la situation où vous avez besoin d'étendre en fonction de requêtes multimédia, 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 ne vous en souciez pas trop, 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édia.

Update 2014-12-28: Extends produit des CSS plus compacts que mixins, mais cet avantage est réduit lorsque CSS est compressé. Si votre serveur prend en charge les fichiers CSS gzippés (cela devrait être le cas!), Alors étend vous n'apporte presque aucun avantage. Vous pouvez donc toujours utiliser mixins! Plus d'informations ici: http://www.sitepoint.com/sass-extend-nobody-told-you/

Une bonne approche consiste à utiliser les deux: créez un mix qui vous permettra beaucoup de personnalisation, puis make s'étend pour les configurations courantes de ce mix. 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 ne devez pas vous souvenir des paramètres des boutons communs, mais que vous avez toujours la possibilité de créer un bouton unique et super unique si vous le souhaitez.

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

15
FreddyBushBoy

À mon avis, les prolongements sont purement pervers et doivent être évités. Voici pourquoi:

vu 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 de mystyles n'est plus bleue (pour de nombreux navigateurs). Qu'est-ce que cela signifie vraiment? Si, à un moment quelconque, vous utilisez une extension où un navigateur peut ne pas comprendre le sélecteur, toutes les autres utilisations de cette extension seront invalidées . Ce comportement permet également une imbrication malveillante:

%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 convient parfaitement tant que vous ne l'utilisez jamais avec des sélecteurs spécifiques à un navigateur. Si vous le faites, il va soudainement détruire les styles où que vous l'ayez utilisé. Essayez plutôt de vous fier aux mixins!

10
clearfix

Utilisez mixins s'il accepte un paramètre dans lequel la sortie compilée changera en fonction de ce que vous y transmettez.

@include opacity(0.1);

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

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

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, alors que je faisais des recherches sur ce thème, j'ai constaté de nombreuses plaintes au sujet de extend, il suffit donc de garder à l'esprit que s'il est possible d'utiliser mixin au lieu d'étendre, sautez simplement expand.

0
Nesha Zoric