No Sass, não consigo discernir a diferença entre usar @include
com um mixin e usar @extend
com uma classe de espaço reservado. Eles não significam a mesma coisa?
No Sass, não consigo discernir a diferença entre usar @include
com um mixin e usar @extend
com uma classe de espaço reservado. Eles não significam a mesma coisa?
Respostas:
As extensões não permitem personalização, mas produzem CSS muito eficiente.
%button
background-color: lightgrey
&:hover, &:active
background-color: white
a
@extend %button
button
@extend %button
Resultado:
a, button {
background-color: lightgrey;
}
a:hover, button:hover, a:active, button:active {
background-color: white;
}
Com mixins, você obtém CSS duplicado, mas pode usar argumentos para modificar o resultado de cada uso.
=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)
Resulta em:
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;
}
Siga este conjunto consecutivo de exemplos de código para ver como você pode tornar seu código mais limpo e mais fácil de manter usando extensões e mixins de forma eficaz: http://thecodingdesigner.com/posts/balancing
Observe que o SASS infelizmente não permite o uso de extensões dentro de consultas de mídia (e o exemplo correspondente do link acima está errado). Na situação em que você precisa estender com base em consultas de mídia, use um mixin:
=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
Resultado:
#main-menu {
display: block;
background-color: pink;
}
@media (min-width: 20em) {
#secondary-menu {
display: block;
background-color: pink;
}
}
A duplicação é inevitável neste caso, mas você não deve se preocupar muito com isso, porque a compressão gzip do servidor da web cuidará disso.
PS Observe que você pode declarar classes de espaço reservado nas consultas de mídia.
Atualização 2014-12-28 : Extensões produzem CSS mais compacto do que os mixins , mas esse benefício é diminuído quando o CSS é compactado com gzip. Se o seu servidor serve CSS compactado (realmente deveria!), O extends não oferece quase nenhum benefício. Então você sempre pode usar mixins ! Mais sobre isso aqui: http://www.sitepoint.com/sass-extend-nobody-told-you/
@extends
substituindo o pai da extensão. Claro que você não pode passar argumentos, mas essa é a única diferença? Nesse caso, fica @extend
apenas @mixin
sem argumentos? Ainda não vejo vantagem ou diferença.
@extend
que possível, pois isso irá produzir CSS mais compacto, que ainda irá comprimir muito bem (é texto ASCII, depois de tudo).
@extend
. Esta é uma micro-otimização aparentemente baseada na intuição e sentimentos viscerais, ao invés de uma compreensão de como o esquema de compressão envolvido realmente funciona. (Além disso: ele ignora a sobrecarga considerável da codificação de transferência gzip sob demanda; a compactação não é gratuita
Uma boa abordagem é usar os dois - criar um mixin que permitirá muitas personalizações e, então, fazer extensões para configurações comuns desse mixin. Por exemplo (sintaxe 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);
}
Isso evita que você chame o mixin my-button repetidamente. Isso também significa que você não precisa se lembrar das configurações dos botões comuns, mas ainda pode criar um botão super único e único, se assim desejar.
Pego esse exemplo de uma postagem no blog que escrevi não muito tempo atrás. Espero que isto ajude.
Na minha opinião, extensões são pura maldade e devem ser evitadas. Aqui está o porquê:
dado o 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}
O seguinte css será gerado:
.mystyle-class, ::-webkit-input-placeholder { //invalid in non-webkit browsers
color: blue;
}
Quando um navegador não entende um seletor, ele invalida toda a linha de seletores. Isso significa que sua preciosa classe mystyle não é mais azul (para muitos navegadores). O que isso realmente significa? Se, a qualquer momento, você usar uma extensão em que um navegador possa não entender o seletor, todos os outros usos da extensão serão invalidados. Este comportamento também permite aninhamento ruim:
%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;}
Resultado:
::-webkit-input-placeholder, .mystyle-class { //invalid in non-webkit browsers
color: blue;
}
::-webkit-input-placeholder {
height: 0;
}
Tl; dr: @extend está perfeitamente ok desde que você nunca o use com nenhum seletor específico do navegador. Se você fizer isso, de repente os estilos serão destruídos, onde quer que você os tenha usado. Tente usar mixins!
Concordo totalmente com a resposta anterior da d4nyll. Existe um texto sobre a opção extender e enquanto eu estava pesquisando este tema encontrei muitas reclamações sobre extender, então apenas tenha em mente que e se houver a possibilidade de usar mixin em vez de extender, é só pular extender.