DEV Community

Cover image for SCSS como você nunca viu
Lucas Souza
Lucas Souza

Posted on

SCSS como você nunca viu

Olá mundo, tudo bom com ocês ? Hoje quero falar um pouco sobre scss e algumas novidades que existem / viram.

Caso queria ver o funcionamento de todas as novas features e/ou modificar algumas coisas basta acessar meu repo scss-like-you-never-seen e seguir o passo-a-passo para visualizar. deixa uma starzinha também ❤️

Antes de tudo !important

Algumas das funcionalidades que vou mostrar não possuem suporte ainda em todos os navegadores, mas é possível testa-las habilitando as flags respectivas em seu navegador.

EX: chrome://flags

basta agora procurar a flag desejada, habilitar e reiniciar o navegador.

Para ter uma leitura mais agradável e ver cada uma das fetures aconselho a clonar o meu repo scss-like-you-never-seen e rodar ele localmente. Dentro de cada pasta do repo existe um README.md explicando a feature.

Eu posso utilizar essas features ?

A documentação do SASS recomenda utilizar o sass ou dart-sass como compilador do projeto e assim conseguindo usar todas essas features sem problema. Caso você esteja utilizando ruby-sass ou lib-sass por exemplo acredito que não será capaz, visto que está deprecated.

Sass module mode

A uns anos atrás foi lançado um feature no scss que é chamado de scss modules basicamente ela permite que o seu estilo funcione como um modulo da aplicação assim liberando alguns recursos interessantes.

Existem duas formas de se utilizar o sass module:

nome.module.scss ou _nome.scss

Nas duas formas você vai poder usufruir de todos os recursos do sass module.

As novidades que vieram foi justamente o @use que permite que você importe um arquivo de estilo dentro de outro, para ser utilizado naquele contexto.

@foward que permite que você importe um arquivo de estilo dentro de outro e que ele seja passado para frente na importação.

Porque o @import é um problema ?

Usando o @import no scss encontramos um problema, um arquivo que possui por exemplo margin: 5rem; no final pode ficar com margin: 10rem;, caso tenha alguma váriavel com o mesmo nome da qual alimenta aquela propriedade, visto que o @import na hora da compilação leva em consideração a ordem.

EXAMPLE:

@import "spacings"; // margin: 10rem;
@import "variables";// margin: 5rem;
@import "mixins";
@import "colors";


.container {
  margin: var(--margin); // essa margin vem do variables
}
Enter fullscreen mode Exit fullscreen mode

Caso a gente altere a ordem de importação, na hora que ocorrer a compilação será alterado o valor.

@import "variables";// margin: 5rem;
@import "spacings"; // margin: 10rem;
@import "mixins";
@import "colors";


.container {
  margin: var(--margin); // essa margin vem do spacings
}
Enter fullscreen mode Exit fullscreen mode

O sass compila de forma procedural, ou seja, o valor da propriedade vai ser alterado de acordo com a última variável encontrada.

O problema que o @use e @foward resolve

@foward

Ele é similar ao @import, você vai passar para frente oque estiver em um contexto, não haverá sobre escrita.

@use

É utilizado no contexto e recebe um namespace, então se o meu arquivo se chama util tudo que eu utilizar ali será necessário passar o util como prefixo.

EX:

@use "_util";

.container {
  margin: util.$margin;
}
Enter fullscreen mode Exit fullscreen mode

Caso não queria usar o namespace, esteja em processo de migração ou deseja utilizar outro nome porque o atual é grande, basta utilizar as e colocar um alias.

@use "_util" as u; // o prefixo agora é `u`
@use "_animations" as *; // não será necessário passar o namespace
Enter fullscreen mode Exit fullscreen mode

7-1 pattern scss

"One file to RULE them all.

One file to FIND them.

One file to BRING them all.

And in the sass way MERGE them".

Esse é o pattern mais utilizado para desfrutar do scss modules, ou seja, o scss modules é um modo de modularizar, cada arquivo é um componente, e cada componente é um modulo. A sua estrutura é a seguinte:
abstracts, vendors, base, layout, components, pages e themes

Existem vários patterns 4-1, 5-1 etc. Tudo vai depender da sua necessidade.

particularmente utilizo bastante esse para meus projetos:

styles/
|
|– base/
|   |– _reset.scss       # Reset/normalize
|   |– _color.scss       # Paleta de cores da aplicação
|   |– _typography.scss  # Typography rules
|   |– _index.scss       # File used to import all base
|
|– layout/
|   |– _navigation.scss   # Navigation
|   |– _grid.scss         # Grid system
|   |– _header.scss       # Header
|   |– _footer.scss       # Footer
|   |– _sidebar.scss      # Sidebar
|   |– _forms.scss        # Forms
|
|– pages/                # Base views -> HOME, ABOUT, CONTACT etc.
|   |– _home.scss        # Home specific styles
|   |– _contact.scss     # Contact specific styles
|
|– themes/
|   |– _theme.scss       # Default theme
|
|– abstract/
|   |– _variables.scss   # Sass Variables
|   |– _functions.scss   # Sass Functions
|   |– _mixins.scss      # Sass Mixins
|   |– _index.scss       # File used to import all abstracts
|
`– _index.scss           # Main Sass file
Enter fullscreen mode Exit fullscreen mode

Container Queries

Para utilizar o @container é necessário definir um query para o componente, fazemos isso da seguinte forma:

.nosso-wrapper {
  container-name: wrapper;
  container-type: inline-size;
}
Enter fullscreen mode Exit fullscreen mode

O que fizemos a cima foi definir o tipo do container e o nome dele.

Note que o @container tem o mesmo funcionamento do @media, entretanto oque diferencia os dois é o container vai ter o adicional de poder utilizar operadores lógicos para definir o tamanho do container.

Oque também diferencia o @container do @media é que ele ajusta o tamanho dos elementos baseado na classe pai e não pelo tamanho do viewport.

EX:

@container wrapper (inline > 50px) {
  .nossa-classe {
    display: grid;
    align-items: center;
    justify-content: center;
  }
}
Enter fullscreen mode Exit fullscreen mode

Compatibilidade: Chrome(🚧Beta), Firefox(🚧Beta), Chromium(🚧Beta) & Safari(✅Suportado)


Extend Rule

O extend é um recurso em que você replica o mesmo estilo de uma classe em outra.

Mas qual a diferença entre o @mixin e o @extend?

O mixin vai gerar uma copia daquele estilo em outro componente na hora da compilação.
Já o extends gera uma referência para a classe original.

EXAMPLE:

/// Mixin input

@mixin placeHolder {
    display: -webkit-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
}
.classe1 {
    @include placeholder;
}
.classe2 {
    @include placeholder;
}

/// Mixin output
.classe1 {
    display: -webkit-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
}
.classe2 {
    display: -webkit-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
}
Enter fullscreen mode Exit fullscreen mode
/// Extend input
.placeHolder {
    display: -webkit-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
}
.classe1 {
    @extend %placeHolder;
}
.classe2 {
    @extend %placeHolder;
}

/// Extend output
.classe1,
.classe2 {
    display: -webkit-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
}
Enter fullscreen mode Exit fullscreen mode

Apesar do @extend ser mais simples, ele é tão poderoso quanto @mixin. Mas isso pode causar alguns problemas.

  • Como a classe .placeHolder é copiada para duas classes, elas são independentes e não se comportam como se fossem uma única classe.
  • Dependendo do comportamento da classe, a classe pai pode não ser a classe original.

Quando usar ou não o @extend?

  • Mixin: Utilize para gerar seu código de modo dinâmico através de variáveis;
  • Extend: Utilize para elementos comuns mas que haverá pouca repetição;

Quando for necessário criar algum tipo de automatização utilize o @mixin, caso contrario utilize o @extend, ou até mesmo os dois juntos.

Compatibilidade: Chrome(✅Suportado), Firefox(✅Suportado), Chromium(✅Suportado) & Safari(✅Suportado)


Has Selector

É uma pseudo classe que permite ao usuário selecionar um elemento do DOM e manipular caso o mesmo exista. Ele não pode ser utilizado dentro de classes css, somente selecionando seletores para seletores.

section:has(div) {
  color: red;
}
Enter fullscreen mode Exit fullscreen mode
<section>
    <h1>Has Selector</h1>
    <div>
      <p>Message</p>
    </div>
  </section>
Enter fullscreen mode Exit fullscreen mode

Compatibilidade: Chrome(🚧Beta), Firefox(🚧Beta), Chromium(🚧Beta) & Safari(✅Suportado)


Layer Rule

Define uma camada de cascata para ser trabalhada, as regas farão parte daquele contexto, não do escopo global da view.

EXAMPLE:

@layer base, component;

@layer base {
  .button {
    background: #eee;
    border: 1px solid #ccc;
    border-radius: 3px;
    color: #333;
    padding: 10px;
    margin: 10px;
  }
}

@layer component {
  .button {
    &__title {
      font-size: 1.5rem;
      font-weight: bold;
    }
    &__icon {
      margin-right: 0.5rem;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

A ordem de declaração de camadas é importante, pois a camada mais acima será a camada mais próxima do contexto, então caso você altere a ordem a prioridade do estilo também mudará.

A propriedade layer pode ser útil para resolver problemas de prioridade não sendo mais necessário usar o atributo important.

Compatibilidade: Chrome(✅Suportado), Firefox(✅Suportado), Chromium(✅Suportado) & Safari(✅Suportado)


Conclusão

Ufa!! Foram muitas coisas que conseguimos ver hoje. algumas ainda estão em estado de desenvolvimento e será necessário ativar flags do seu navegador para testar.

Caso queria ver o código funcional de cada funcionalidade apresentada aqui basta acessar o meu repo scss-like-you-never-seen deixa uma star!

Até a próxima.

Top comments (0)