В Sass я не могу четко различить разницу между использованием @include
с миксином и использованием @extend
с классом-заполнителем. Разве они не означают одно и то же?
В Sass я не могу четко различить разницу между использованием @include
с миксином и использованием @extend
с классом-заполнителем. Разве они не означают одно и то же?
Ответы:
Расширения не позволяют настраивать, но они создают очень эффективный 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/
@extends
, переопределив родительское расширение. Конечно, вы не можете передавать аргументы, но разве это единственная разница? В таком случае, это @extend
просто @mixin
без аргументов? Я до сих пор не вижу преимущества или разницы.
@extend
там, где это возможно, так как это даст более компактный CSS, который все равно будет сжиматься довольно хорошо (в конце концов, это текст ASCII).
@extend
. Это микрооптимизация, по-видимому, основанная на интуиции и интуиции, а не на понимании того, как на самом деле работает задействованная схема сжатия. (Также: он игнорирует значительные накладные расходы на кодирование передачи gzip по требованию; сжатие не является бесплатным!;)
Хороший подход - использовать оба варианта: создать миксин, который позволит вам настраивать множество параметров, а затем сделать расширения для общих конфигураций этого миксина. Например (синтаксис 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. Это также означает, что вам не нужно запоминать настройки для общих кнопок, но вы все равно можете создать супер-уникальную одноразовую кнопку, если захотите.
Я взял этот пример из сообщения в блоге, которое написал недавно. Надеюсь это поможет.
На мой взгляд, расширение - чистое зло, и его следует избегать. Вот почему:
учитывая 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 совершенно нормально, если вы никогда не используете его с какими-либо специальными селекторами браузера. Если вы это сделаете, он внезапно разрушит стили, где бы вы его ни использовали. Попробуйте вместо этого полагаться на миксины!
Используйте миксины, если он принимает параметр, при этом скомпилированный вывод будет меняться в зависимости от того, что вы ему передаете.
@include opacity(0.1);
Используйте расширение (с заполнителем) для любых статических повторяемых блоков стилей.
color: blue;
font-weight: bold;
font-size: 2em;
Я полностью согласен с предыдущим ответом d4nyll. Есть текст о опции расширения, и пока я исследовал эту тему, я обнаружил много жалоб на расширение, так что просто имейте в виду, что если есть возможность использовать миксин вместо расширения, просто пропустите расширение.