Verwenden Sie @include vs @extend in Sass?

92

In Sass kann ich den Unterschied zwischen der Verwendung @includemit einem Mixin und der Verwendung @extendmit einer Platzhalterklasse nicht ganz erkennen . Sind sie nicht dasselbe?

temporärer_Benutzername
quelle
2
Mit include können Sie die Basisklasse nicht erweitern, sondern nur Optionen hinzufügen. Raten Sie einfach, sass-lang.com/docs/yardoc/… und sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
CodeGroover
1
Auch @CodeGroover, kein nützlicher Kommentar, vielleicht haben Sie die Frage falsch verstanden. Wenn Sie dies lesen, erhalten Sie
temporärer_Benutzername
4
Jedes Mal, wenn Sie ein Mixin ohne Parameter verwenden, ist eine Erweiterung effizienter. Mit freundlicher Genehmigung von Chris
Abhijeet

Antworten:

86

Erweiterungen erlauben keine Anpassung, produzieren jedoch sehr effizientes CSS.

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

a
  @extend %button

button
  @extend %button

Ergebnis:

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

Mit Mixins erhalten Sie doppeltes CSS, aber Sie können Argumente verwenden, um das Ergebnis für jede Verwendung zu ändern.

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

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

Befolgen Sie diese fortlaufenden Codebeispiele, um zu sehen, wie Sie Ihren Code sauberer und wartbarer machen können, indem Sie Erweiterungen und Mixins effektiv verwenden: http://thecodingdesigner.com/posts/balancing

Beachten Sie, dass SASS die Verwendung von Erweiterungen innerhalb von Medienabfragen leider nicht zulässt (und das entsprechende Beispiel über den obigen Link ist falsch). Verwenden Sie in Situationen, in denen Sie basierend auf Medienabfragen eine Erweiterung benötigen, ein 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

Ergebnis:

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

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

In diesem Fall ist eine Duplizierung unvermeidlich, aber Sie sollten sich nicht zu sehr darum kümmern, da sich die gzip-Komprimierung des Webservers darum kümmert.

PS Beachten Sie, dass Sie Platzhalterklassen in Medienabfragen deklarieren können.

Update 2014.12.28 : Verlängert Produkte kompakten CSS als Mixins tun, aber diese Leistung vermindert wird , wenn CSS gzipped wird. Wenn Ihr Server gzipped CSS dient (es soll wirklich!), Dann reichen Sie fast keinen Nutzen. Sie können also immer Mixins verwenden ! Mehr dazu hier: http://www.sitepoint.com/sass-extend-nobody-told-you/

Andrey Mikhaylov - lolmaus
quelle
2
Ich denke nicht, dass das ganz richtig ist ... Sie können anpassen, @extendsindem Sie die übergeordnete Erweiterung überschreiben. Natürlich können Sie keine Argumente weitergeben, aber ist das dann der einzige Unterschied? In diesem Fall ist @extendnur @mixinohne Argumente? Ich sehe immer noch keinen Vorteil oder Unterschied.
temporärer_Benutzername
2
Hier sind ein paar andere Macken ... stackoverflow.com/questions/30744625/…
Toni Leigh
Ich würde den Aspekt "gibt Ihnen fast keinen Nutzen" des letzten Absatzes dort sorgfältig interpretieren. Die Gzip-Komprimierung ist ein wörterbuchbasierter Huffman-Codierer. Wenn die Wiederholung also weit genug voneinander entfernt erfolgt, ist der Text nicht im Wörterbuch vorhanden und die Komprimierungsverhältnisse leiden darunter. Ich ziehe noch immer , @extendwo möglich, da dies wird kompakten CSS produzieren, die ziemlich gut noch komprimieren werden (es ist ASCII - Text, nachdem alle).
Amcgregor
@amcgregor, der Unterschied ist vernachlässigbar.
Andrey Mikhaylov - lolmaus
@ AndreyMikhaylov-lolmaus Ich stimme zu! Ich würde erwarten, dass der Unterschied über das Kabel im Wesentlichen nicht messbar ist, unabhängig von der Wahl für etwas bis zu etwa einem Megabyte generierten CSS, abgesehen von der Tatsache, dass das unkomprimierte Endergebnis im Speicher bei Verwendung kompakter ist @extend. Dies ist eine Mikrooptimierung, die anscheinend eher auf Intuition und Bauchgefühl basiert als auf einem Verständnis der tatsächlichen Funktionsweise des Komprimierungsschemas. (Auch: es ignoriert den erheblichen Aufwand der On-Demand-GZIP-Übertragungscodierung; Komprimierung ist nicht kostenlos !;)
Amcgregor
18

Ein guter Ansatz ist es, beides zu verwenden - erstellen Sie ein Mixin, das Ihnen viele Anpassungen ermöglicht, und erweitern Sie dann die gängigen Konfigurationen dieses Mixins. Zum Beispiel (SCSS-Syntax):

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

Dies erspart Ihnen das wiederholte Aufrufen des My-Button-Mixins. Es bedeutet auch, dass Sie sich nicht an die Einstellungen für allgemeine Schaltflächen erinnern müssen, aber dennoch die Möglichkeit haben, eine super einzigartige, einmalige Schaltfläche zu erstellen, falls Sie dies wünschen.

Ich nehme dieses Beispiel aus einem Blog-Beitrag, den ich vor kurzem geschrieben habe. Hoffe das hilft.

FreddyBushBoy
quelle
12

Meiner Meinung nach sind Erweiterungen rein böse und sollten vermieden werden. Hier ist warum:

angesichts der 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}

Das folgende CSS wird generiert:

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

Wenn ein Browser einen Selektor nicht versteht, macht er die gesamte Auswahlzeile ungültig. Dies bedeutet, dass Ihre wertvolle Mystyle-Klasse nicht mehr blau ist (für viele Browser). Was bedeutet das wirklich? Wenn Sie zu irgendeinem Zeitpunkt eine Erweiterung verwenden, bei der ein Browser den Selektor möglicherweise nicht versteht, wird jede andere Verwendung der Erweiterung ungültig. Dieses Verhalten ermöglicht auch böses Verschachteln:

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

Ergebnis:

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

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

Tl; dr: @extend ist vollkommen in Ordnung, solange Sie es nie mit einem Browser-spezifischen Selektor verwenden. Wenn Sie dies tun, werden die Stile plötzlich überall dort abgerissen, wo Sie sie verwendet haben. Versuchen Sie stattdessen, sich auf Mixins zu verlassen!

clearfix
quelle
4
Interessante Anmerkung
simhumileco
4

Verwenden Sie Mixins, wenn ein Parameter akzeptiert wird, bei dem sich die kompilierte Ausgabe abhängig von der Übergabe ändert.

@include opacity(0.1);

Verwenden Sie "Erweitern" (mit Platzhalter) für statisch wiederholbare Stilblöcke.

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

Ich stimme der vorherigen Antwort von d4nyll voll und ganz zu. Es gibt einen Text über die Option "Erweitern", und während ich dieses Thema recherchierte, fand ich viele Beschwerden über die Option "Erweitern". Denken Sie also daran, und wenn die Möglichkeit besteht, Mixin anstelle von "Erweitern" zu verwenden, überspringen Sie einfach "Erweitern".

Nesha Zoric
quelle