Sass: Include ou Placeholder Extend? Qual a diferença? Quando utilizar?

Olá, pessoal! No post de hoje vamos esclarecer uma dúvida comum entre os programadores que utilizam o Sass, que é quando utilizar o @mixin ou @extend.

Antes, precisamos entender cada uma dessas funções do Sass.

Entendendo o @mixin no Sass

Algumas coisas em CSS são um pouco tediosas para escrever, especialmente com o CSS3 e os muitos prefixos de fornecedores existentes. Um mixin permite criar grupos de declarações CSS que você deseja reutilizar em todo o site. Você pode até passar valores como parâmetro para tornar seu mixin mais flexível. Um bom uso de um mixin é para prefixos de fornecedores. Aqui está um exemplo para transformar.

Código Sass:

@mixin transform($property) {  -webkit-transform: $property;      -ms-transform: $property;          transform: $property;}.box { @include transform(rotate(30deg)); }

Código CSS3 gerado:

.box {  -webkit-transform: rotate(30deg);  -ms-transform: rotate(30deg);  transform: rotate(30deg);}

Sendo assim, podemos ver que o código do mixin é anexado ao código da classe que ele é chamado, e se diversas classes chamarem o mesmo código este será copiado em cada uma. Vejamos um exemplo abaixo.

Código Sass:

@mixin transform($property) {
-webkit-transform: $property;
-ms-transform: $property;
transform: $property;
}
.box { @include transform(rotate(30deg)); }
.box2 { @include transform(rotate(30deg)); }
.box3 { @include transform(rotate(30deg)); }

Código CSS3 gerado:

.box {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
.box2 {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
.box3 {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}

Observe que as três classes agora possuem o mesmo código. Mas isso é a forma mais simples de escrever esse CSS3? Vejamos outra forma de escrever o mesmo código.

Entendendo o @extend

Este é um dos recursos mais úteis do Sass. Usar o @extend permite compartilhar um conjunto de propriedades CSS de um seletor para outro. Isso ajuda a manter seu Sass mais limpo. Nesse exemplo, criaremos uma série simples de mensagens para erros, avisos e sucessos usando outro recurso que combina com as classes placeholders e extend. Uma classe placeholder é um tipo especial de classe que só imprime quando é estendida e pode ajudar a manter seu CSS compilado limpo e completo.

Código Sass:

// Este CSS não será compilado porque %equal-heights nunca é estendido.%equal-heights {
display: flex;
flex-wrap: wrap;
}

//
Este CSS será compilado porque %message-shared é estendido.%message-shared {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}

.message {
@extend %message-shared;
}

.success {
@extend %message-shared;
border-color: green;
}

.error {
@extend %message-shared;
border-color: red;
}

.warning {
@extend %message-shared;
border-color: yellow;
}

O que o código acima faz é dizer .message.success.error, & .warning para se comportar como %message-shared. Isso significa que qualquer lugar que %message-shared apareça, .message.success.error, & .warning também aparecem. A mágica acontece no CSS gerado, onde cada uma dessas classes obterá as mesmas propriedades CSS que %message-shared. Isso ajuda a evitar a necessidade de escrever vários nomes de classes em elementos HTML.

Você pode estender seletores mais simples, além de classes, mas extender placeholders no Sass é a maneira mais fácil de garantir que você não esteja estendendo uma classe aninhada em outros locais em seus estilos, o que pode resultar em seletores indesejados em seu código CSS.

Quando você gera seu CSS, ele ficará assim. Observe que o CSS em %equal-heights não é compilado porque nunca é usado.

Código CSS3 gerado:

.message, .success, .error, .warning {  border: 1px solid #cccccc;  padding: 10px;  color: #333;}.success {  border-color: green;}.error {  border-color: red;}.warning {  border-color: yellow;}

Observe que as classes .message, .success, .error, .warning ficaram todas na mesma linha, economizando código CSS, o que resultará em um código mais leve para o carregamento da página.

@extend vs @mixin

Podemos observar que há grandes diferenças em ambos os casos, e essas diferenças implicam em quando utilizar um @mixin ou @extend.

Vejamos o código de exemplo do @mixin, utilizando o @extend e placeholder:

Código Sass com @mixin e @extend:

@mixin transform($property) {
-webkit-transform: $property;
-ms-transform: $property;
transform: $property;
}
%box{
@include transform(rotate(30deg));
}
.box { @extend %box }
.box2 { @extend %box }
.box3 { @extend %box }

Código CSS3 gerado:

.box3, .box2, .box {
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}

Observe que nesse caso, não conseguimos reproduzir o código apenas com o placeholder, e isso é uma das características únicas do @mixin, o uso de parâmetros, com o placeholder não conseguimos passar um parâmetro, apenas estender o código existente.

Vejamos outro exemplo para que possamos fixar melhor esses conceitos.

Código Sass com @mixin:

@mixin flex{    display: -webkit-box;    display: -ms-flexbox;    display: -webkit-flex;    display: flex;}.class1 {    @include flex;}.class2 {    @include flex;}.class3 {    @include flex;}.class4 {    @include flex;}.class5 {    @include flex;}

Código CSS3 gerado:

.class1 {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
.class2 {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
.class3 {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
.class4 {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
.class5 {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}

Observe que o código foi replicado em cada uma das classes, o que é uma boa prática caso as classes não tenham nenhuma relação, ou seja, se essas classes não são para uma mesma finalidade, não faz sentido agruparmos, como acontece no exemplo a seguir com o placeholder e @extend.

Código Sass com placeholder e @extend:

%flex{    display: -webkit-box;    display: -ms-flexbox;    display: -webkit-flex;    display: flex;}.class1 {    @extend %flex;}.class2 {    @extend %flex;}.class3 {    @extend %flex;}.class4 {    @extend %flex;}.class5 {    @extend %flex;}

Código CSS3 gerado com placeholder e @extend:

.class5, .class4, .class3, .class2, .class1 {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}

Observe que o código agora está mais limpo, porém nem sempre isso pode ser o esperado.

Conclusão

Mixin faz com que nos possamos criar códigos Sass que funcionam, bem parecidos como funções que conhecemos em linguagens convencionais, podendo passar parâmetros para cada situação, o que torna o Sass mais dinâmico, porém, isso faz com que o código do Mixin seja reescrido em cada chamada, retornando o código completo em cada seletor que o utiliza.

Extend nos trás a possibilidade de trabalharmos com os seletores do tipo placeholders, além de classes comuns, que funciona como uma Herança, ele vai herdar todas as propriedades que estão sendo extendidas, resulta com um código agrupado, mais limpo.

Se você ainda não conseguiu entender quando utilizar o @mixin e quando utilizar o @extend, aqui vai uma dica e boa prática, utilize o @extend apenas quando as classes tiverem a mesma finalidade, como o exemplo que vimos das mensagens, pois todas as classes tem o mesmo propósito. No caso do Mixin, utilize ele para facilitar a sua programação, como no caso de precisar chamar a mesma ou as mesmas propriedades em diversas classes sem o mesmo propósito, como é o caso do @mixin flex, criado nos exemplos anteriores.

E aí, Gostou?

Espero que tenhamos sanado a sua dúvida, e caso queira se aprofundar mais sobre o assunto, temos um curso completo de Sass pode ser acessado logo abaixo, com um super desconto, exclusivo para os nossos leitores.

Ah, não esqueçam de curtir e seguir a gente nas redes sociais e se inscrever na nossa newsletter, para ficar sabendo em primeira mão sobre os próximos posts e cursos disponíveis, além de vagas de emprego na área de programação.

Forte abraço e até o próximo post.