Использование @include vs @extend в Sass?

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

Ответ 1

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

Ответ 2

Хороший подход заключается в том, чтобы использовать оба метода - создать mixin, который позволит вам выполнить множество настроек, а затем сделать расширения для общих конфигураций этого mixin. Например (синтаксис 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. Это также означает, что вам не нужно запоминать настройки для обычных кнопок, но у вас все еще есть возможность сделать супер уникальную одноразовую кнопку, которую вы должны выбрать.

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

Ответ 3

По моему мнению, это чистое зло, и его следует избегать. Вот почему:

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

Ответ 4

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

@include opacity(0.1);

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

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

Ответ 5

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