Introduçao ao Sass

14/07/2021
Rafael
CSS
Introduçao ao Sass

Vamos dar nossos primeiros passos com este poderoso pré-processador CSS.

Com o Sass (Syntactically Awesome Style Sheets), podemos dar "superpoderes" ao nosso CSS, utilizando recursos como variáveis, mixins, aninhamento de código, laços de repetição, dentre outros. Abordarei algumas destas funcionalidades neste post, então vamos lá!

Instalação

Você pode realizar a instalação de duas maneiras: através de programas de terceiros, como o Scout-App, ou usando a CLI. Aqui nós utilizaremos a segunda opção, para isso, abra um terminal e execute o comando:

npm i -g sass 

Após o processo de instalação, execute sass --version para conferir se foi instalado corretamente, você verá algo parecido com isso:

Screenshot do terminal

.sass vs .scss

O Sass aceita basicamente duas extensões de arquivos: .sass e .scss. A principal diferença fica na sintaxe, no primeiro o que vale é a indentação, já o segundo é bem similar ao CSS padrão. Veja o exemplo:

/* ==== .sass ==== */
.search input 
  padding: 0.5rem 1rem
  width: 100%
  font-size: 1rem
  border: 2px solid #00000088

  &:focus 
    border: 2px solid $primary-color


/* ==== .scss ==== */
.search input {
  padding: 0.5rem 1rem;
  width: 100%;
  font-size: 1rem;
  border: 2px solid #00000088;

  &:focus {
    border: 2px solid $primary-color;
  }
}

Compilando para CSS

Como realizamos a instalação por CLI, usaremos o terminal para compilar nosso código. Na verdade, é bem simples, basta usar o comando sass apontando o arquivo ou a pasta de origem e em seguida o local de destino:

sass assets/scss/styles.scss:assets/css/styles.css

# ou
sass assets/scss:assets/css

Porém, toda vez que salvarmos nosso arquivo, teremos que executar novamente esse comando. Para tornar esse processo mais prático, você pode passar a flag --watch, que vai fazer com que o Sass fique "observando" as alterações feitas a cada salvamento e compilar novamente o código:

sass --watch assets/scss:assets/css

Outra flag interessante é a style, que define o estilo de saída, que pode ser: expanded que é o padrão, e o compressed, que resulta em um código minificado, ou seja, vai gerar todos os estilos em uma só linha:

# default
sass --watch assets/scss:assets/css --style expanded

# minificado
sass --watch assets/scss:assets/css --style compressed

Depois de processado, o código do exemplo usado anteriormente resultará no seguinte CSS:

/* ==== --style expanded ==== */
.search input {
  padding: 0.5rem 1rem;
  width: 100%;
  font-size: 1rem;
  border: 2px solid #00000088;
}

.search input:focus {
  border: 2px solid #5544ee;
}


/* ==== --style compressed ==== */
.search input{padding:.5rem 1rem;width:100%;font-size:1rem;border:2px solid #00000088}.search input:focus{border:2px solid #54e}

Variáveis

Assim como no CSS padrão, é possível armazenar dados como, por exemplo, fontes, cores e tamanhos em variáveis. Dessa forma, conseguimos reaproveitar os valores armazenados em qualquer parte do nosso código. Para declarar uma variável basta iniciá-la com um $ antes do seu nome:

/* ==== scss ==== */
$font-primary: Arial, Helvetica, sans-serif;
$color-white: #f4f4f4;
$color-blue: #5544ee;

.btn {
  font-family: $font-primary;
  color: $color-white;
  background: $color-blue;
}


/* ==== css gerado ==== */
.btn {
  font-family: Arial, Helvetica, sans-serif;
  color: #f4f4f4;
  background: #5544ee;
}

Aninhamento

Essa funcionalidade permite agrupar seletores, sendo bem útil para manter o código organizado e mais visual :

/* ==== scss ==== */
nav ul {
  display: flex;
  background: $primary-color;
  list-style: none;

  a {
    padding: 0.625rem;
    text-decoration: none;
    color: $color-white;
    transition: opacity 0.2s ease-in-out;

    &:hover {
      opacity: 0.7;
    }
  }
}


/* ==== css gerado ==== */
nav ul {
  display: flex;
  background: #5544ee;
  list-style: none;
}

nav ul a {
  padding: 0.625rem;
  text-decoration: none;
  color: #f4f4f4;
  transition: opacity 0.2s ease-in-out;
}

nav ul a:hover {
  opacity: 0.7;
}

Só tenha cuidado: prefira usar no máximo uns três níveis no aninhamento, pois além de aumentar a especificidade dos seletores, o excesso de aninhamento vai fazer com que o código fique parecendo uma árvore de natal 🎄🎄.

Mixins

Mixins são agrupamentos de código que podem ser reaproveitados. Para declarar um mixin, usamos @mixin e em seguida definimos um nome para ele. Para usá-lo, basta usar @include antes do nome do mixin:

/* ==== scss ==== */
@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.card {
  @include flex-center;
}


/* ==== css gerado ==== */
.card {
  display: flex;
  align-items: center;
  justify-content: center;
}

Eles também aceitam parâmetros:

/* ====
center é o valor padrão
caso o mixin não receba argumentos
==== */
@mixin flex($align: center, $justify: center) {
  display: flex;
  align-items: $align;
  justify-content: $justify;
}

.card {
  @include flex;

  &__footer {
    @include flex(initial, space-around);
  }
}


/* ==== css gerado ==== */
.card {
  display: flex;
  align-items: center;
  justify-content: center;
}

.card__footer {
  display: flex;
  align-items: initial;
  justify-content: space-around;
}

Laços de repetição

De forma similar ao que vemos nas linguagens de programação, também temos laços de repetição no aqui.

@for

O @for vai contar de um número até outro e é usado de dois modos: @for <variável> from <expressão> to <expressão> ou @for <variável> from <expressão> through <expressão>. No to a expressão final é excluída como parte da contagem, já no through ela é incluída.

/* ==== scss ==== */
@for $i from 1 to 6 {
  .text-#{$i} {
    font-size: $i * 8px;
  }
}


/* ==== css gerado ==== */
.text-1 {
  font-size: 8px;
}

.text-2 {
  font-size: 16px;
}

.text-3 {
  font-size: 24px;
}

.text-4 {
  font-size: 32px;
}

.text-5 {
  font-size: 40px;
}

Caso utilizássemos o through, seria criada mais uma classe com nome .text-6 e font-size: 48px.

@while

O @while vai executar enquanto determinada condição for verdadeira. O código abaixo vai ter o mesmo resultado do anterior:

$i: 1;

@while $i < 6 {
  .text-#{$i} {
    font-size: $i * 8px;
  }

  $i: $i + 1;
}

Lembre sempre de incrementar a variável para evitar um loop infinito.

Estruturas condicionais (@if, @else if, @else)

O @if vai definir os estilos verificando se uma condição é verdadeira. Podemos continuar testando com @else if e, caso todas verificações retornem falso, o estilo dentro do bloco @else vai ser definido:

/* ==== scss ==== */
@mixin text-size($val) {
  @if $val == big {
    font-size: 32px;
  }

  @else if $val == medium {
    font-size: 20px;
  }

  @else {
    font-size: 16px;
  }
}

.title {
  text-align: center;
  @include text-size(big);
}


/* ==== css gerado ==== */
.title {
  text-align: center;
  font-size: 32px;
}

Conclusão

Se você gostou e quer se aprofundar mais sobre os recursos deste pré-processador, confira a documentação completa do Sass. Também recomendo assistir esta excelente Masterclass, onde o Mayk Brito aborda vários conceitos e mostra como colocar seu CSS num outro nível!