Используете @include против @extend в Sass?

94

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

временное_имя_пользователя
источник
2
include не расширяет базовый класс, он просто добавляет параметры. Просто советую прочитать sass-lang.com/docs/yardoc/… и sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend
CodeGroover
1
Кроме того, @CodeGroover, вообще бесполезный комментарий, возможно, вы неправильно поняли вопрос. Прочитав это, вы получите
временное_имя_пользователя
4
Каждый раз, когда вы используете миксин без параметров, расширение будет более эффективным. Предоставлено Крисом
Абхиджит

Ответы:

89

Расширения не позволяют настраивать, но они создают очень эффективный 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;
}

С миксинами вы получаете дублированный 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 : Extends производит более компактный CSS, чем миксины , но это преимущество уменьшается при сжатии CSS с помощью gzip. Если ваш сервер обслуживает сжатый с помощью gzip CSS (это действительно необходимо!), Тогда extends почти не принесет вам пользы. Так что вы всегда можете использовать миксины ! Подробнее об этом здесь: http://www.sitepoint.com/sass-extend-nobody-told-you/

Андрей Михайлов - лолмаус
источник
2
Я не думаю, что это совсем точно ... вы можете настроить @extends, переопределив родительское расширение. Конечно, вы не можете передавать аргументы, но разве это единственная разница? В таком случае, это @extendпросто @mixinбез аргументов? Я до сих пор не вижу преимущества или разницы.
temporary_user_name
2
Вот еще несколько причуд ... stackoverflow.com/questions/30744625/…
Тони Ли
Я был бы осторожен, интерпретируя аспект последнего абзаца «почти не приносит вам пользы». Сжатие Gzip - это кодировщик Хаффмана на основе словаря, поэтому, если повторение происходит достаточно далеко друг от друга, текст не будет присутствовать в словаре, и степень сжатия пострадает. Я по-прежнему всегда предпочитаю @extendтам, где это возможно, так как это даст более компактный CSS, который все равно будет сжиматься довольно хорошо (в конце концов, это текст ASCII).
amcgregor
@amcgregor, разница незначительна.
Андрей Михайлов - lolmaus
@ AndreyMikhaylov-lolmaus Согласен! Я ожидал, что разница будет практически неизмеримой по сети, независимо от выбора сгенерированного CSS размером до мегабайта или около того, за исключением того факта, что несжатый конечный результат в памяти будет более компактным @extend. Это микрооптимизация, по-видимому, основанная на интуиции и интуиции, а не на понимании того, как на самом деле работает задействованная схема сжатия. (Также: он игнорирует значительные накладные расходы на кодирование передачи gzip по требованию; сжатие не является бесплатным!;)
amcgregor
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. Это также означает, что вам не нужно запоминать настройки для общих кнопок, но вы все равно можете создать супер-уникальную одноразовую кнопку, если захотите.

Я взял этот пример из сообщения в блоге, которое написал недавно. Надеюсь это поможет.

ФреддиБушМальчик
источник
14

На мой взгляд, расширение - чистое зло, и его следует избегать. Вот почему:

учитывая 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 совершенно нормально, если вы никогда не используете его с какими-либо специальными селекторами браузера. Если вы это сделаете, он внезапно разрушит стили, где бы вы его ни использовали. Попробуйте вместо этого полагаться на миксины!

clearfix
источник
4
Интересное примечание
simhumileco
4

Используйте миксины, если он принимает параметр, при этом скомпилированный вывод будет меняться в зависимости от того, что вы ему передаете.

@include opacity(0.1);

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

color: blue;
font-weight: bold;
font-size: 2em;
d4nyll
источник
0

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

Неша Зорич
источник