Usando @include vs @extend in Sass?


93

In Sass, non riesco a discernere la differenza tra l'utilizzo @includecon un mixin e l'utilizzo @extendcon una classe segnaposto. Non equivalgono alla stessa cosa?


2
include non ti dà la classe base estesa, aggiunge solo opzioni. Ti consiglio solo di leggere sass-lang.com/docs/yardoc/… e sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
CodeGroover

1
Inoltre, @CodeGroover, non è affatto un commento utile, forse hai frainteso la domanda. La lettura di questo fornisce informazioni più utili: gist.github.com/antsa/970172
temporary_user_name

4
Ogni volta che useresti un mixin senza parametri, un'estensione sarà più efficiente. Courtesy Chris
Abhijeet

Risposte:


87

Le estensioni non consentono la personalizzazione, ma producono CSS molto efficienti.

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

a
  @extend %button

button
  @extend %button

Risultato:

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

Con i mixin, ottieni CSS duplicati, ma puoi usare gli argomenti per modificare il risultato per ogni utilizzo.

=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)

Risultati in:

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

Segui questa serie consecutiva di esempi di codice per vedere come puoi rendere il tuo codice più pulito e più manutenibile utilizzando estensioni e mixin in modo efficace: http://thecodingdesigner.com/posts/balancing

Si noti che SASS sfortunatamente non consente l'uso di estensioni all'interno di query multimediali (e l'esempio corrispondente dal collegamento sopra è sbagliato). Nella situazione in cui è necessario estendere in base a query multimediali, utilizzare 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

Risultato:

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

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

La duplicazione è inevitabile in questo caso, ma non dovresti preoccupartene troppo perché la compressione gzip del server web si prenderà cura di essa.

PS Notare che è possibile dichiarare classi segnaposto all'interno di media query.

Aggiornamento 2014/12/28 : Estende prodotti più compatto CSS di mixins fanno, ma questo vantaggio è diminuito quando CSS viene compresso con gzip. Se il tuo server serve CSS gzip (dovrebbe davvero!), Allora le estensioni non ti danno quasi alcun vantaggio. Quindi puoi sempre usare i mixin ! Maggiori informazioni su questo qui: http://www.sitepoint.com/sass-extend-nobody-told-you/


2
Non penso che non sia del tutto accurato ... puoi personalizzare @extendssovrascrivendo l'estensione genitore. Ovviamente non puoi passare argomenti, ma è questa l'unica differenza? In tal caso, è @extendsolo @mixinsenza argomenti? Continuo a non vedere il vantaggio o la differenza.
temporary_user_name

2
Ecco alcune altre stranezze ... stackoverflow.com/questions/30744625/…
Toni Leigh

Farei attenzione a interpretare l'aspetto "non ti dà quasi alcun vantaggio" dell'ultimo paragrafo, lì. La compressione Gzip è un codificatore di Huffman basato su dizionario, quindi se la ripetizione avviene abbastanza lontano, il testo non sarà presente nel dizionario e i rapporti di compressione ne risentiranno. Io preferisco sempre ancora @extend, se possibile, in quanto questo si produrrà più compatto CSS, che sarà comunque comprimere (è testo ASCII, dopo tutto) abbastanza bene.
amcgregor

@amcgregor, la differenza è trascurabile.
Andrey Mikhaylov - lolmaus

@ AndreyMikhaylov-lolmaus sono d'accordo! Mi aspetto che la differenza sia essenzialmente non misurabile in rete, indipendentemente dalla scelta per qualsiasi cosa fino a un megabyte circa di CSS generato, a parte il fatto che il risultato finale non compresso in memoria sarà più compatto utilizzando @extend. Questa è una microottimizzazione apparentemente basata sull'intuizione e sui sentimenti viscerali, piuttosto che sulla comprensione di come funziona effettivamente lo schema di compressione coinvolto. (Inoltre: ignora il considerevole sovraccarico della codifica di trasferimento gzip su richiesta; la compressione non è gratuita!;)
amcgregor

18

Un buon approccio è quello di utilizzare entrambi: creare un mixin che ti permetta molte personalizzazioni e quindi creare estensioni per le configurazioni comuni di quel mixin. Ad esempio (sintassi 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);
}

Questo ti evita di chiamare ripetutamente il mixaggio my-button. Significa anche che non devi ricordare le impostazioni per i pulsanti comuni, ma hai comunque la possibilità di creare un pulsante unico e unico se lo desideri.

Prendo questo esempio da un post sul blog che ho scritto non molto tempo fa. Spero che questo ti aiuti.


12

Secondo me le prolunghe sono puro male e dovrebbero essere evitate. Ecco perché:

dato lo 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}

Verrà generato il seguente css:

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

Quando un browser non comprende un selettore, invalida l'intera riga di selettori. Ciò significa che la tua preziosa classe mystyle non è più blu (per molti browser). Cosa significa veramente? Se in qualsiasi momento si utilizza un'estensione in cui un browser potrebbe non comprendere il selettore, ogni altro utilizzo dell'estensione verrà invalidata. Questo comportamento consente anche l'annidamento malvagio:

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

Risultato:

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

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

Tl; dr: @extend è perfettamente ok fintanto che non lo usi mai con nessun selettore specifico del browser. Se lo fai, improvvisamente abbatterà gli stili ovunque tu lo abbia usato. Prova invece a fare affidamento sui mixin!


4
Nota interessante
simhumileco

4

Usa mixin se accetta un parametro, dove l'output compilato cambierà a seconda di cosa ci passi.

@include opacity(0.1);

Usa estensione (con segnaposto) per tutti i blocchi di stili statici ripetibili.

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

0

Sono totalmente d'accordo con la precedente risposta di d4nyll. C'è un testo sull'opzione di estensione e mentre stavo ricercando questo tema ho trovato molte lamentele sull'estensione, quindi tienilo a mente e se c'è la possibilità di usare mixin invece di estendere, salta l'estensione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.