Używasz @include vs @extend w Sass?

94

W Sassie nie do końca dostrzegam różnicę między używaniem @includez mieszanką a używaniem @extendz klasą zastępczą. Czy nie sprowadzają się do tego samego?

nazwa_użytkownika_tymczasowego
źródło
2
include nie zapewnia rozszerzenia klasy bazowej, po prostu dodaje opcje. Po prostu radzę przeczytać sass-lang.com/docs/yardoc/… i sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
CodeGroover
1
Poza tym @CodeGroover, komentarz w ogóle nie jest przydatny, być może źle zrozumiałeś pytanie. Czytanie tego daje więcej przydatnych informacji: gist.github.com/antsa/970172
tymczasowy_nazwa_użytkownika
4
Za każdym razem, gdy użyjesz miksu bez parametru, rozszerzenie będzie bardziej wydajne. Dzięki uprzejmości Chris
Abhijeet

Odpowiedzi:

89

Rozszerzenia nie pozwalają na dostosowywanie, ale generują bardzo wydajny CSS.

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

a
  @extend %button

button
  @extend %button

Wynik:

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

Dzięki mieszankom otrzymujesz zduplikowane CSS, ale możesz użyć argumentów, aby zmodyfikować wynik dla każdego użycia.

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

Prowadzi do:

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

Postępuj zgodnie z poniższym zestawem przykładów kodu, aby zobaczyć, jak możesz uczynić swój kod czystszym i łatwiejszym w utrzymaniu, efektywnie stosując rozszerzenia i mieszanki: http://thecodingdesigner.com/posts/balancing

Zwróć uwagę, że SASS niestety nie pozwala na używanie rozszerzeń w zapytaniach o media (a odpowiedni przykład z powyższego linku jest nieprawidłowy). W sytuacji, gdy potrzebujesz rozszerzyć na podstawie zapytań o media, użyj miksu:

=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

Wynik:

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

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

W tym przypadku powielanie jest nieuniknione, ale nie powinieneś się tym zbytnio przejmować, ponieważ zajmie się tym kompresja gzip serwera WWW.

PS Pamiętaj, że w zapytaniach o media możesz zadeklarować klasy zastępcze.

Aktualizacja 2014-12-28 : Rozszerzenia tworzą bardziej zwarty CSS niż miksery , ale ta korzyść jest mniejsza , gdy CSS jest spakowany gzipem. Jeśli twój serwer obsługuje CSS spakowany gzipem (naprawdę powinien!), Rozszerzenia nie dają prawie żadnych korzyści. Więc zawsze możesz używać mixinów ! Więcej na ten temat tutaj: http://www.sitepoint.com/sass-extend-nobody-told-you/

Andrey Mikhaylov - lolmaus
źródło
2
Nie sądzę, żeby to było do końca dokładne ... możesz dostosować @extends, zastępując rodzica rozszerzenia. Oczywiście nie możesz przekazać argumentów, ale czy to jedyna różnica? W takim razie jest @extendpo prostu @mixinbez argumentów? Nadal nie widzę korzyści ani różnicy.
temporary_user_name
2
Oto kilka innych dziwactw ... stackoverflow.com/questions/30744625/
Toni Leigh
Byłbym ostrożny, interpretując tam aspekt „nie daje prawie żadnych korzyści” z ostatniego akapitu. Kompresja Gzip to oparty na słownikach koder Huffmana, więc jeśli powtórzenie nastąpi wystarczająco daleko od siebie, tekst nie będzie obecny w słowniku i ucierpi na tym współczynniki kompresji. Nadal zawsze wolę, @extendgdzie to możliwe, ponieważ da to bardziej zwarty CSS, który nadal będzie dość dobrze kompresowany (w końcu jest to tekst ASCII).
amcgregor
@amcgregor, różnica jest znikoma.
Andrey Mikhaylov - lolmaus 25.07.19
@ AndreyMikhaylov-lolmaus Zgadzam się! Spodziewałbym się, że różnica będzie zasadniczo nie do zmierzenia w sieci, niezależnie od wyboru dla czegokolwiek do jednego megabajta generowanego CSS, poza faktem, że nieskompresowany wynik końcowy w pamięci będzie mniejszy @extend. Jest to mikro-optymalizacja, która pozornie opiera się na intuicji i przeczuciach, a nie na zrozumieniu, jak faktycznie działa schemat kompresji. (Ponadto: ignoruje znaczny narzut związany z kodowaniem transferu gzip na żądanie; kompresja nie jest darmowa
!;
18

Dobrym podejściem jest użycie obu - stwórz mixin, który pozwoli ci na wiele dostosowań, a następnie rozszerzy typowe konfiguracje tego miksu. Na przykład (składnia 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);
}

Dzięki temu nie musisz w kółko wywoływać miksera my-button. Oznacza to również, że nie musisz pamiętać ustawień typowych przycisków, ale nadal masz możliwość stworzenia super unikalnego, jednorazowego przycisku, jeśli wybierzesz.

Biorę ten przykład z posta na blogu, który napisałem niedawno. Mam nadzieję że to pomoże.

FreddyBushBoy
źródło
14

Moim zdaniem rozciągnięte są czystym złem i należy ich unikać. Oto dlaczego:

biorąc pod uwagę 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}

Zostanie wygenerowany następujący plik CSS:

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

Gdy przeglądarka nie rozpoznaje selektora, unieważnia całą linię selektorów. Oznacza to, że twoja cenna klasa mystyle nie jest już niebieska (dla wielu przeglądarek). Co to tak naprawdę znaczy? Jeśli w jakimkolwiek momencie użyjesz rozszerzenia, w którym przeglądarka może nie zrozumieć selektora, każde inne użycie rozszerzenia zostanie unieważnione. To zachowanie pozwala również na złe zagnieżdżanie:

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

Wynik:

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

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

Tl; dr: @extend jest całkowicie w porządku, o ile nigdy nie używasz go z żadnymi specjalistycznymi selektorami przeglądarki. Jeśli to zrobisz, nagle zniszczy style w każdym miejscu, w którym go użyłeś. Zamiast tego spróbuj polegać na mieszankach!

clearfix
źródło
4
Ciekawa notatka
simhumileco
4

Użyj mixins, jeśli akceptuje parametr, gdzie skompilowane wyjście będzie się zmieniać w zależności od tego, co do niego przekażesz.

@include opacity(0.1);

Użyj rozszerzenia (z symbolem zastępczym) dla dowolnych statycznych powtarzalnych bloków stylów.

color: blue;
font-weight: bold;
font-size: 2em;
d4nyll
źródło
0

Całkowicie zgadzam się z poprzednią odpowiedzią d4nyll. Jest tam tekst o opcji rozszerzania i kiedy badałem ten temat, znalazłem wiele skarg dotyczących rozszerzenia, więc pamiętaj o tym i jeśli istnieje możliwość użycia mixin zamiast rozszerzenia, po prostu pomiń rozszerzenie.

Nesha Zoric
źródło