Використовуєте @include vs @extend у Sass?


93

У Sass я не можу точно розрізнити різницю між використанням @includeз мікшином та використанням @extendіз класом-заповнювачем. Чи не складають вони одне і те ж?


2
include не дає вам розширити базовий клас, він просто додає опції. Просто порадьте прочитати sass-lang.com/docs/yardoc/… та sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
CodeGroover

1
Крім того, @CodeGroover, не корисний коментар, можливо, ви неправильно зрозуміли питання. Читання цього дає більше корисної інформації: gist.github.com/antsa/970172
тимчасове_користувацьке

4
Кожного разу, коли ви використовуєте мікшин без параметра, розширення буде більш ефективним. Ввічливість Кріс
Абхієет

Відповіді:


87

Розширення не дозволяють налаштування, але вони створюють дуже ефективний CSS.

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

a
  @extend %button

button
  @extend %button

Результат:

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

За допомогою mixins ви отримуєте дубльований CSS, але ви можете використовувати аргументи, щоб змінити результат для кожного використання.

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

Призводить до:

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

Будь ласка, дотримуйтесь цього послідовного набору прикладів коду, щоб побачити, як ви можете зробити свій код чистішим та ремонтопридатнішим, ефективно використовуючи розширення та комбінування: http://thecodingdesigner.com/posts/balancing

Зауважте, що SASS, на жаль, не дозволяє використовувати розширення всередині медіа-запитів (а відповідний приклад із наведеного вище посилання помилковий). У ситуації, коли вам потрібно розширити на основі медіа-запитів, використовуйте комбінацію:

=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

Результат:

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

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

Дублювання у цьому випадку неминуче, але вам не слід надто дбати про це, оскільки стиснення gzip веб-сервера подбає про це.

PS Зауважте, що ви можете оголосити класи заповнювачів у медіа-запитах.

Оновлення 2014-12-28 : Розширення виробляє більш компактний CSS, ніж міксини , але ця перевага зменшується, коли CSS gzipped. Якщо ваш сервер обслуговує gzipped CSS (це дійсно повинно!), То розширення майже не дають вам переваг. Тож ви завжди можете використовувати міксини ! Докладніше про це тут: http://www.sitepoint.com/sass-extend-nobody-told-you/


2
Я не думаю, що це не зовсім точно ... Ви можете налаштувати, замінивши @extendsбатьківський номер розширення. Звичайно, ви не можете передавати аргументи, але тоді це єдина різниця? У такому випадку @extendпросто @mixinбез аргументів? Я все ще не бачу переваги чи різниці.
тимчасове_користувацьке

2
Ось ще кілька примх ... stackoverflow.com/questions/30744625/…
Тоні Лі

Я був би обережним, тлумачачи аспект останнього абзацу "майже не приносить користі". Стиснення Gzip - це кодування Хаффмана на основі словника, тому, якщо повторення відбудеться досить далеко, текст не буде присутній у словнику, і ступінь стиснення постраждає. Я все ще завжди віддаю перевагу, @extendде це можливо, оскільки це дасть більш компактний CSS, який все одно буде досить стискатися (зрештою, це текст ASCII).
amcgregor

@amcgregor, різниця незначна.
Андрій Михайлов - lolmaus

@ AndreyMikhaylov-lolmaus Я згоден! Я би очікував, що різниця буде по суті незмірна по дроту, незалежно від вибору будь-чого до мегабайта або близько того, згенерованого CSS, крім того, що несжатий кінцевий результат в пам'яті буде більш компактним при використанні @extend. Це мікрооптимізація, яка, мабуть, базується на інтуїції та почуттях кишечника, а не на розумінні того, як насправді працює задіяна схема стиснення. (Також: він ігнорує значні накладні витрати на кодування передачі gzip на вимогу; стиснення не є безкоштовним
!;

18

Хорошим підходом є використання обох - створити мікшин, який дозволить вам багато налаштувати, а потім зробити розширення для загальних конфігурацій цього міксіну. Наприклад (синтаксис 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);
}

Це позбавляє вас від повторного виклику мікшину my-button. Це також означає, що вам не потрібно запам'ятовувати налаштування загальних кнопок, але ви все ще можете зробити надзвичайно унікальну, одноразову кнопку, якщо ви вирішите.

Я беру цей приклад із допису в блозі, який я написав недавно. Сподіваюся, це допомагає.


12

На мою думку, розширення - це чисте зло, і їх слід уникати. Ось чому:

враховуючи 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}

Буде створено такий css:

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

Коли браузер не розуміє селектора, він анулює весь рядок селекторів. Це означає, що ваш дорогий клас mystyle вже не блакитний (для багатьох браузерів). Що це насправді означає? Якщо в будь-який час ви використовуєте розширення, коли браузер може не зрозуміти селектора, кожне інше використання розширення буде визнано недійсним. Така поведінка також дозволяє вкладати зло:

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

Результат:

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

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

Tl; dr: @extend цілком нормально, якщо ви ніколи не використовуєте його з будь-якими спеціальними селекторами браузера. Якщо ви це зробите, це раптово зруйнує стилі, де б ви їх не використовували. Спробуйте замість цього покластися на міксини!


4
Цікава примітка
simhumileco

4

Використовуйте mixins, якщо він приймає параметр, де скомпільований вивід буде змінюватися залежно від того, що ви в нього передаєте.

@include opacity(0.1);

Використовуйте розширення (із заповнювачем) для будь-яких статичних повторюваних блоків стилів.

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

0

Я повністю згоден з попередньою відповіддю d4nyll. Існує текст про опцію розширення, і, досліджуючи цю тему, я знайшов багато нарікань на розширення, тому просто майте на увазі, що і якщо є можливість використовувати міксин замість розширення, просто пропустіть розширення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.