Iniciando no Sass com os dois pés na porta

lixeletto

Camilo Micheletto

Posted on August 21, 2020

Iniciando no Sass com os dois pés na porta

Note: I may translate this text to english in the future, until that, if you're not a brazillian portuguese speaker, you can translate this test yourself with this extension (if your navigator did not propted you to do so).


Esse texto é pra você que sente que tá todo mundo ao seu redor usando Sass menos você

Geralmente quem quer começar a aprender Sass se mete com as seguintes perguntas:

Qual a diferença entre Sass e Scss?

Sass é a linguagem, é um CSS estendido, em sua forma original é escrito com aninhamentos identados igualzinho ao HTML, o que torna mais tranquilo escrever relações de elementos pais com os filhos. Já o Scss é uma sintaxe dessa linguagem que é muito parecida com CSS. Ambas linguagens estendem as funções do CSS e são pré-processadas e transformadas em CSS antes de ir pro navegador. A grande maioria das vezes que você ouvir sobre Sass subentenda que a sintaxe utilizada é Scss, é a mais popular.

Pré-processamento?

O pré processamento é uma rotina que traduz seu código Sass pra CSS. Pode ser feito com Gulp, Grunt, Webpack entre n outros, o que pode ser uma barreira pra algumas pessoas que querem aprender Sass mas sentem dificuldade com esses automatizadores. A gente vai mastigar essa dificuldade usando o Live Sass Compiler - uma extensão do VSCode .

Processando Sass com Live Sass Compiler

Primeiro baixe a extensão Live Sass Compiler no Marketplace do VSCode

A extensão vai procurar todos os arquivos de Sass e criar um CSS normal e um minificado à partir deles na mesma pasta. Caso queira configurar qual pasta você deseja que os arquivos finais sejam salvos, basta ir nas configurações da extensão e acessar o settings.json dela.

Gif configurando a pasta do Live Sass Compiler no settings json

Ai basta adicionar essa seção de código ao documento (ou alterar caso ela exista). Nessa seção você define o formato do código - se é expandido ou minificado - qual o nome das extensões de cada um e qual local você quer salvar. Eu deixo a opção generateMap como false porque o map a gente não utiliza.

"liveSassCompile.settings.formats":[ 
    {
        "format": "expanded",
        "extensionName": ".css",
        "savePath": "app/css"
    },
    {
        "format": "compressed",
        "extensionName": ".min.css",
        "savePath": "app/css"
    },
  ],
  "liveSassCompile.settings.generateMap": false,
Enter fullscreen mode Exit fullscreen mode

Caso você tenha mais de um arquivo, você pode editar as configurações pra desconsiderar os arquivos dentro de alguns diretórios:

"liveSassCompile.settings.excludeList": [

    "**/node_modules/**",
    ".vscode/**",

    //adicione sua pasta aqui!!
    "**/exemplo/**" 
  ],
Enter fullscreen mode Exit fullscreen mode

O ideal é que caso você divida as folhas de estilo por componentes, crie uma folha de estilo principal e dentro dela você importe todas as suas folhas de estilo, dessa forma você só precisa compilar um único arquivo.

Dentro do main.scss

@import './components/button.scss';
@import './components/reset.scss';
@import './components/variables.scss';
Enter fullscreen mode Exit fullscreen mode

Quer fazer na unha? Recomendo esse artigo que ensina a compilar Sass com Gulp.

Estrutura de arquivos

Caso o tamanho do seu código justifique, é importante criarmos uma separação de responsabilidades dentro das folhas de estilo para que o código fique mais fácil de manter e corrigir.
Existe um padrão de estrutura de Sass em projetos chamado 7 x 1 não é alemã que separa os elementos em 7 pastas diferentes que são importadas pra dentro de um arquivo base, a estrutura fica assim:

sass/
|
|– abstracts/
|   |– _variables.scss    # Sass Variables
|   |– _functions.scss    # Sass Functions
|   |– _mixins.scss       # Sass Mixins
|   |– _placeholders.scss # Sass Placeholders
|
|– base/
|   |– _reset.scss        # Reset/normalize
|   |– _typography.scss   # Typography rules
|   …                     # Etc.
|
|– components/
|   |– _buttons.scss      # Buttons
|   |– _carousel.scss     # Carousel
|   |– _cover.scss        # Cover
|   |– _dropdown.scss     # Dropdown
|   …                     # Etc.
|
|– layout/
|   |– _navigation.scss   # Navigation
|   |– _grid.scss         # Grid system
|   |– _header.scss       # Header
|   |– _footer.scss       # Footer
|   |– _sidebar.scss      # Sidebar
|   |– _forms.scss        # Forms
|   …                     # Etc.
|
|– pages/
|   |– _home.scss         # Home specific styles
|   |– _contact.scss      # Contact specific styles
|   …                     # Etc.
|
|– themes/
|   |– _theme.scss        # Default theme
|   |– _admin.scss        # Admin theme
|   …                     # Etc.
|
|– vendors/
|   |– _bootstrap.scss    # Bootstrap
|   |– _jquery-ui.scss    # jQuery UI
|   …                     # Etc.
|
`– main.scss              # Main Sass file
Enter fullscreen mode Exit fullscreen mode

Para entender melhor como funciona essa pattern leia essa documentação.

Variáveis Sass x variáveis CSS

Existem algumas diferenças entre as variáveis Sass e as variáveis CSS:

Variáveis Sass são estáticas

A variável Sass após compilada vira um valor estático, já a do CSS continua uma variável, podendo ser editada na web usando do developer tools do navegador e também acessada usando javascript.

Variáveis CSS não funcionam como parâmetros de media-queries

@media screen and (max-width: var(--small-screen)) {
  /* Vai dar pau */
}

@media screen and (max-width: $small-screen) {
  /* Vai funfar :) */
}
Enter fullscreen mode Exit fullscreen mode

Você não pode usar variáveis de CSS dentro dos @media queries, mas você pode usar variáveis Sass. Isso é útil quando você quer predefinir em variáveis os seus breakpoints ou colocar valores dinâmicos neles.

Variáveis Sass não são escopadas pelos elementos do DOM

:root {
 --font-size: 3em;
}

@media screen and (max-width: 432px) {
/* No viewport com 432px de largura o font-size vai ser de 2em */
  --font-size: 2em;
}
Enter fullscreen mode Exit fullscreen mode

No CSS as variáveis são escopadas dentro dos seletores e herdadas pelos seletores filhos, já as variáveis Sass não possuem escopo, pois como são pré-processadas antes de chegar no browser, elas não acessam o DOM. A sintaxe e utilização das duas são parecidas:

//CSS
--btn-color: #CD4445;

//Sass
$btn-color : #CD4445;
Enter fullscreen mode Exit fullscreen mode

Uma implementação interessante desses escopos é criar temas de cores e implementá-los dentro de diferentes seletores:

:root {
  --primary: #34CED1;
  --secondary: #FCFAF7;
  --success: #505155; 
}

.dark-theme {
  --primary: #FCFAF7;
  --secondary: #505155;
  --success: #34CED1; 
}
Enter fullscreen mode Exit fullscreen mode

Para implementar basta inserir a classe .dark-theme no body do documento, como o seletor de classe tem especificidade maior que a do seletor :root, os estilos do tema vão sobrepor os de base:

<body class="dark-theme">
  <!-- As variáveis dentro dessa classe serão herdadas
  por todos os elementos do body! -->
</body> 

Enter fullscreen mode Exit fullscreen mode

Você pode usar Sass pra mais do que escrever CSS aninhado

Eu vejo muita gente utilizando Sass apenas pra escrever CSS chique, e eu não julgo eu julgo sim, mas é possível fazer muito melhor do que isso, principalmente se você escreve usando algum padrão de CSS como BEM ou SMACSS é possível aninhar elementos dentro dos seus respectivos blocos de maneira muito intuitiva . Olha o exemplo de um botão feito com Sass x CSS gerado.

👉 Sass

.btn{
  all: unset;
  color: #FAFAFA;
  background-color: #1A1A1A;
  height: 40px;
  padding: 5px 10px;
  transition: background .6s ease-in;
  width: fit-content;
  &--red {
    background-color: #F02947;
    &:hover {
      background-color: #D63C53;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

👉 CSS

.btn {
  all: unset;
  color: #FAFAFA;
  background-color: #1A1A1A;
  height: 40px;
  padding: 5px 10px;
  transition: background .6s ease-in;
  width: fit-content;
}

.btn--red {
  background-color: #F02947;
}

.btn--red:hover {
  background-color: #D63C53;
}
Enter fullscreen mode Exit fullscreen mode

Dentro do Sass podemos usar o caractere ampersand (e comercial &) para concatenar os nomes dos seletores, assim podemos agrupar os blocos de maneira mais lógica. O ideal também é separarmos o código por bloco e criar aninhamentos dentro de cada bloco, isso evita que façamos aninhamentos extremamente complexos como esse aqui:

body{
  /*...*/
  nav{
    /*...*/
    ul{
      /*...*/
      li{
        /*...*/
        a{
          /*Imagina o CSS disso aqui*/
        }
      }
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

O ideal é que o aninhamento tenha no máximo 3 níveis, caso você precise usar mais que isso, é interessante utilizar a at-rule @at-root. Isso faz com que o seletor utilizado seja compilado na raiz do documento e não aninhado no código, tornando o CSS mais legível. Você pode ler mais sobre o @at-root nessa documentação.
Pra quem quiser saber mais sobre BEM, recomendo esse artigo do Julio Lozovei.

Utilizando maps, listas e loops

Claro que você pode aninhar dentro de .btn os modificadores --red, --blue, --green, cada um com seu respectivo :hover, mas tem um jeito muitíssimo mais prático de fazer isso - utilizando os maps. Você talvez conheça o map como Hash ou Objeto, um map recebe uma chave e um valor dentro de si. É possível também guardar mais elementos utilizando uma notação de lista.

👉 map

$font-weights: (
 "regular": 400,
 "medium": 500,
 "bold": 700,
);
Enter fullscreen mode Exit fullscreen mode

👉 lista

$buttons: (
 "regular"   $primary $white,
 "danger"    $danger  $white,
 "success"   $success $white,
 "secondary" $white   $darkgrey
);
Enter fullscreen mode Exit fullscreen mode

Dentro da lista $buttons, temos uma string com o nome do botão, a cor do plano de fundo e a cor da fonte, dessa forma podemos utilizar dessa lista para criar os diferentes botões utilizando um loop @each, que funciona de maneira bem parecida com o for in ou o for each de algumas linguagens de programação.

Essa função abaixo diz que para cada elemento da lista $buttons, ele vai fazer uma determinada ação. Nesse caso a nossa lista tem grupos de três elementos separados por vírgula. Dentro do @each definimos uma variável pra cada elemento de um grupo da lista, assim, a cada iteração que o @each fizer em um grupo, essas variáveis vão assumir valores diferentes. Lembra que dentro de .btn aninhamos seus modificadores com cada uma de suas cores? podemos fazer a mesma coisa dentro do @each, só que ao concatenar seletores com variáveis, utilizamos a notação #{ } e passamos dentro dela o nome da variável, no caso $name.

$buttons: (
 "regular"   $primary $white,
 "danger"    $danger  $white,
 "success"   $success $white,
 "secondary" $white   $darkgrey
);

.btn{
  all: unset;
  color: #FAFAFA;
  background-color: #1A1A1A;
  height: 40px;
  padding: 5px 10px;
  transition: background .6s ease-in;
  width: fit-content;

  @each $name, $bg, $color in $buttons {
    &__#{$name} {
       /*... código */
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Dentro desse seletor podemos colocar a variável $bg como background-color e $color como color. É possível também aninhar com o pseudo-classe :hover e passar uma cor mais escura utilizando a uma função de cor do Scss chamada darken. Darken recebe dois parâmetros - a variável ou valor da cor e a porcentagem em que se deve escurecer a cor.

$buttons: (
 "regular"   $primary $white,
 "danger"    $danger  $white,
 "success"   $success $white,
 "secondary" $white   $darkgrey
);

.btn{
  all: unset;
  color: #FAFAFA;
  background-color: #1A1A1A;
  height: 40px;
  padding: 5px 10px;
  transition: background .6s ease-in;
  width: fit-content;

  @each $name, $bg, $color in $buttons {
    &__#{$name} {
      background-color: $bg;
      color: $color;
      &:hover {
        background-color: darken($bg, 10%);
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Ao usar as funções de cor nativas do Sass você não precisa manualmente declarar os níveis de brilho das suas cores padrão. Pra conhecer todas as funções de cor você pode olhar nessa documentação.

Você pode ver esse código completo no meu Codepen, o padrão fica bem parecido com o Bootstrap (que por acaso foi construido com Sass).

Dessa mesma forma você pode construir modificadores para seus componentes de maneira dinâmica utilizando como base seus design tokens.

No próximo artigo eu vou falar mais sobre funções, mixins, blocos e cálculos. Se isso foi útil pra você, compartilha com quem você acha que isso vai ajudar. Dúvidas, sugestões? Comente ou manda um salve lá no meu Twitter @lixeletto.

💖 💪 🙅 🚩
lixeletto
Camilo Micheletto

Posted on August 21, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related