Funções e mixins do Sass

  1. Funções
  2. Mixins

Nesse tutorial, mostraremos como você pode criar suas próprias funções e mixins. Como os dois são muito parecidos, eles foram colocados no mesmo tutorial.

Funções

Funções retornam algum valor quando são chamadas e podem receber argumentos. Elas são criadas usando a diretiva @function. A sintaxe de criação de uma função é a seguinte:

@function nome(argumentos) {
  @return valor;
}

Exemplo:

@function col-width($cols, $cols-row) {
  @return percentage($cols / $cols-row);
}

@function header-width() {
  @return 100%;
}

header {
  width: header-width();
}

aside {
  width: col-width(3, 12);
}
header {
  width: 100%; }

aside {
  width: 25%; }

Como você pode ver, as funções são chamadas da mesma forma que qualquer outra função de Sass. Você também pode usar valores padrões em argumentos de funções e usar keyword arguments para chamá-las:

@function col-width($cols, $cols-row: 12) {
  @return percentage($cols / $cols-row);
}

@function header-width() {
  @return 100%;
}

header {
  width: header-width();
}

aside {
  width: col-width(3);
}

article {
  width: col-width($cols: 3, $cols-row: 6);
}
header {
  width: 100%; }

aside {
  width: 25%; }

article {
  width: 50%; }

O Sass também suporta argumentos variáveis em funções, que basicamente fazem com que uma função possa receber um número indefinido de argumentos. Esses argumentos são definidos com o nome do argumento seguido por reticências:

@function nome(..., $argumento...) {
  ...
}

Como a sintaxe mostra, outros argumentos podem ser colocados antes dos argumentos variáveis. Exemplo de função com argumentos variáveis:

@function box-shadows($shadows...) {
  @return $shadows;
}

.card-image {
  box-shadows: box-shadows(3px 7px, 0px 4px, 10px 5px);
}
.card-image {
  box-shadow: 3px 7px, 0px 4px, 10px 5px; }

É recomendável prefixar as suas funções para evitar conflitos de nomes e para que os leitores saibam que elas não são funções nativas do Sass ou do CSS. Exemplo: company-col-width($cols).

Mixins

Enquanto funções retornam um valor, mixins incluem estilos quando são chamados. Essa é a principal diferença entre mixins e funções. Inclusive, a sintaxe de criação do mixin é bem parecida com a sintaxe da função:

@mixin nome(argumentos) {
  Estilo
}

O estilo do mixin pode ter propriedades e seletores. O mixin é incluído usando a sintaxe abaixo:

@include nome(argumentos);

Vejamos um exemplo que define alguns mixins e os inclui:

@mixin cabecalho {
  width: 100%;
  padding-left: 1em;
  padding-right: 1em;
  margin-bottom: 2em;
}

@mixin botao($font-color, $font-size: 1em) {
  font-size: $font-size;
  padding: $font-size/2;
  background-color: #426800;
  color: $font-color;
}

header {
  @include cabecalho;
}

.small-button {
  @include botao(#fff);
}

.medium-button {
  @include botao($font-color: #a930d8, $font-size: 1.2em);
}
header {
  width: 100%;
  padding-left: 1em;
  padding-right: 1em;
  margin-bottom: 2em; }

.small-button {
  font-size: 1em;
  padding: 0.5em;
  background-color: #426800;
  color: #fff; }

.medium-button {
  font-size: 1.2em;
  padding: 0.6em;
  background-color: #426800;
  color: #a930d8; }

Como você viu no exemplo, nem todo mixin tem argumentos. Eles são opcionais. Quando o mixin não tem argumentos, os parênteses não são usados nem para definir o mixin e nem para inclui-lo. No exemplo, os mixins foram incluídos sempre dentro de regras, mas eles também podem ser incluídos fora de regras. E também dá pra usar keyword arguments e valores padrões de argumentos em mixins, como você pode ver na definição e na inclusão do mixin botao.

Também dá pra usar argumentos variáveis em mixins, da mesma forma que eles são usados em funções.

Mixins podem incluir outros mixins, embora isso não tenha sido feito nos exemplos. Eles também podem receber estilo de quem os inclui. Para isso, o mixin precisa apenas definir onde o estilo será injetado usando a diretiva @content, e o estilo deve ser passado entre chaves no momento da inclusão do mixin. Exemplo:

@mixin cabecalho($side-padding) {
  width: 100%;
  padding-left: $side-padding;
  padding-right: $side-padding;
  margin-bottom: 2em;
  @content;
}

header {
  @include cabecalho(1em) {
    background-color: blue;
  }
}
header {
  width: 100%;
  padding-left: 1em;
  padding-right: 1em;
  margin-bottom: 2em;
  background-color: blue; }

Como você viu acima, argumentos podem ser incluídos normalmente mesmo quando a diretiva @content é usada.

Uma observação importante é que o estilo que é passado para o mixin é avaliado no escopo onde ele é passado, e não no escopo do mixin. Assim, variáveis locais ao mixin não podem ser usadas nos estilos que são incluídos usando @content:

@mixin cabecalho($side-padding, $color) {
  width: 100%;
  padding-left: $side-padding;
  padding-right: $side-padding;
  margin-bottom: 2em;
  color: $color;
  @content;
}

header {
  $color: white;
  @include cabecalho(1em, black) {
    background-color: $color;
  }
}
header {
  width: 100%;
  padding-left: 1em;
  padding-right: 1em;
  margin-bottom: 2em;
  color: black;
  background-color: white; }