Iniciando no Sass com os dois pés na porta
Tags: sass, css, bem, beginners
Published: 2020-08-21 23:42:27

_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](https://chrome.google.com/webstore/detail/google-translate/aapbdbdomjkkjkaonfhkkikfgjllcleb?hl=pt) (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](https://marketplace.visualstudio.com/items?itemName=ritwickdey.live-sass)

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](https://dev-to-uploads.s3.amazonaws.com/i/7neamxu8r1dhzhgkftl6.gif)

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.

```json
"liveSassCompile.settings.formats":[ 
    {
        "format": "expanded",
        "extensionName": ".css",
        "savePath": "app/css"
    },
    {
        "format": "compressed",
        "extensionName": ".min.css",
        "savePath": "app/css"
    },
  ],
  "liveSassCompile.settings.generateMap": false,
```

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

```json
"liveSassCompile.settings.excludeList": [

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

    //adicione sua pasta aqui!!
    "**/exemplo/**" 
  ],
```

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_
```scss
@import './components/button.scss';
@import './components/reset.scss';
@import './components/variables.scss';
```
Quer fazer na unha? Recomendo [esse artigo que ensina a compilar Sass com Gulp](https://css-tricks.com/gulp-for-beginners/).

## 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
```

Para entender melhor como funciona essa pattern leia [essa documentação](https://sass-guidelin.es/#the-7-1-pattern).

## 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
```css
@media screen and (max-width: var(--small-screen)) {
  /* Vai dar pau */
}

@media screen and (max-width: $small-screen) {
  /* Vai funfar :) */
}
```
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
```css
: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;
}
```
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:

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

//Sass
$btn-color : #CD4445;
```

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

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

.dark-theme {
  --primary: #FCFAF7;
  --secondary: #505155;
  --success: #34CED1; 
}
```

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:

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

```

##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.

:point_right: Sass
```scss
.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;
    }
  }
}
```

:point_right: CSS
```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;
}
```

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:

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

```

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](https://sass-lang.com/documentation/at-rules/at-root). 
 Pra quem quiser saber mais sobre BEM, recomendo [esse artigo do Julio Lozovei](https://medium.com/trainingcenter/bem-em-5min-f5c80fd23439).

##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. 

:point_right: map
```scss
$font-weights: (
 "regular": 400,
 "medium": 500,
 "bold": 700,
);
```

:point_right: lista
```scss
$buttons: (
 "regular"   $primary $white,
 "danger"    $danger  $white,
 "success"   $success $white,
 "secondary" $white   $darkgrey
);
```

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`.

```scss
$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 */
    }
  }
}
```

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.

```scss
$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%);
      }
    }
  }
}
```

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](https://sass-lang.com/documentation/modules/color).

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).
{% codepen https://codepen.io/camilo-micheletto/pen/MWywyaw %}


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](https://twitter.com/lixeletto).