CSS: 7 casos de uso para Custom Properties
Tags: ptbr, webdev, beginners, css
Published: 2020-05-02 07:26:35

As [Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) (também conhecidas como Variáveis ​​CSS) permitem armazenar valores de propriedades para reutilização em nossas folhas de estilo. Se isso é relativamente novo para você, fica a dúvida de quando você deve utilizá-los ao invés de variáveis do seu pré-processador de CSS (se de fato você usa um pré-processador). Atualmente, estou usando muito as Custom Properties no meu fluxo de trabalho e pensei em agrupar alguns dos casos de uso aqui.

Este não é um guia detalhado de como as Custom Properties funcionam, portanto, se você quiser algumas dicas rápidas, temos os seguintes casos:

# Funções de Cores

As Custom Properties não representam apenas valores de propriedades inteiras - elas também podem ser usadas para armazenar valores parciais. Um caso de uso comumente citado está nas funções de cores CSS. O [HSLA](https://tympanus.net/codrops/css_reference/hsla/) funciona bem com *custom properties*, permitindo que desenvolvedores tenham um nível de controle sem precedentes quando se trata de misturar cores.

```css
.some-element {
  background-color: hsla(
    var(--h, 120),
    var(--s, 50),
    var(--l, 50),
    var(--a, 1)
  );
}

.some-element.darker {
  --l: 20;
}
```

Também podemos fazer algumas coisas muito legais, como calcular cores complementares. [Este artigo](https://blog.logrocket.com/how-to-create-better-themes-with-css-variables-5a3744105c74/) que escrevi no ano passado é um guia muito mais detalhado sobre manipulação de cores com *custom properties*, e [Sara Soueidan também tem um ótimo artigo](https://www.sarasoueidan.com/blog/hex-rgb-to-hsl/) sobre o assunto.

# Propriedades Abreviadas

Se você estiver usando uma propriedade abreviada como `animation`, e precisar alterar um valor para um elemento diferente, escrever toda a propriedade novamente pode ser suscetível a erros e adicionar uma carga extra de manutenção. Usando *custom properties*, podemos ajustar um valor único na propriedade abreviada com muita facilidade:

```css
.some-element {
  animation: var(--animationName, pulse) var(--duration, 2000ms) ease-in-out
    infinite;
}

.some-element.faster {
  --duration: 500ms;
}

.some-element.shaking {
  --animationName: shake;
}
```

# Valores Repetidos

Suponha que temos um elemento que tenha um valor consistente para o *padding-top*, porém, um valor igual para todos os outros lados. Escrever o seguinte pode ser um pouco entediante, especialmente se quisermos ajustar os valores do *padding*:

```css
.some-element {
  padding: 150px 20px 20px 20px;
}

@media (min-width: 50em) {
  padding: 150px 60px 60px 60px;
}
```

Usar *custom properties* significa que temos apenas um local para ajustar esse *padding*. Melhor ainda, se é um valor padrão usado em todo o site, podemos declará-lo em uma variável parcial, no arquivo de configuração ou [tokens de design do site](https://css-tricks.com/what-are-design-tokens/).

```css
:root {
  --pad: 20px;
}

@media (min-width: 50em) {
  :root {
    --pad: 60px;
  }
}

.some-element {
  padding: 150px var(--pad) var(--pad) var(--pad);
}
```

# Cálculos Complexos

As *custom properties* podem ser realmente úteis para armazenar valores calculados (a partir da função `calc()`), os quais podem ser calculados a partir de outras propriedades personalizadas. Um exemplo é o cálculo de cores complementares, como mencionado anteriormente. Outra é quando você deseja calcular o inverso de uma propriedade. Escrevi um artigo para o CSS Tricks há pouco tempo sobre como [calcular o valor reverso de uma *"easing-curve"*](https://css-tricks.com/reversing-an-easing-curve/) com *custom properties*.

Costumo usar *custom properties* com `clip-path` se eu precisar calcular um caminho em relação a outro ou em relação a variáveis ​​conhecidas. O código a seguir, de uma demonstração recente, calcula os pontos do caminho do clipe para dois pseudo elementos para dar a aparência de um elemento que está sendo dividido em duas partes.

```css
.element {
  --top: 20%;
  --bottom: 80%;
  --gap: 1rem;
  --offset: calc(var(--gap) / 2);
}

.element::before {
  clip-path: polygon(
    calc(var(--top) + var(--offset)) 0,
    100% 0,
    100% 100%,
    calc(var(--bottom) + var(--offset)) 100%
  );
}

.element::after {
  clip-path: polygon(
    calc(var(--top) - var(--offset)) 0,
    calc(var(--bottom) - var(--offset)) 100%,
    0 100%,
    0 0
  );
}
```

https://codepen.io/michellebarker/full/yLLGVMQ

# Animações Escalonadas

Se quisermos escalonar animações para vários elementos filhos, podemos definir um `animation-delay` de maneira elegante com *custom properties* utilizando o índice do elemento:

```css
.element {
  --delay: calc(var(--i, 0) * 500ms);
  animation: fadeIn 1000ms var(--delay, 0ms);
}

.element:nth-child(2) {
  --i: 2;
}

.element:nth-child(3) {
  --i: 3;
}
```

https://codepen.io/michellebarker/full/VwYYpqw

Infelizmente, atualmente temos que atribuir a variável explicitamente, o que poderia ser um problema se tivermos um número indeterminado de filhos. [Splitting.JS](https://splitting.js.org/) é uma excelente biblioteca JavaScript que cuida disso, atribuindo o índice do elemento como uma variável e é muito útil para esse tipo de animação escalonada. Mas seria ótimo não ter que usar JS!

Adam Argyle enviou recentemente [uma proposta para duas novas funções CSS](https://github.com/w3c/csswg-drafts/issues/4559), `sibling-count()` e `sibling-index()`, o que seria um divisor de águas, possibilitando muitas coisas novas com CSS. Eles não estão nem perto de serem adotados por qualquer navegador neste momento, mas seria uma adição incrivelmente poderosa, portanto, fique de olho.

# Grids Responsivos

Já [escrevi sobre isso anteriormente](https://css-irl.info/super-powered-layouts/), mas as *custom properties* podem ajudar a facilitar o gerenciamento de layouts complexos em *grid*. Suponha que tenhamos um *grid* de 8 colunas, e queremos mudar para um *grid* de 12 colunas em um *breakpoint* específico:

```css
:root {
  --noOfColumns: 8;
}

@media (min-width: 60em) {
  :root {
    --noOfColumns: 12;
  }
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--noOfColumns), 1fr);
}
```

Não precisamos escrever o valor inteiro da propriedade sempre que quisermos atualizar o número de colunas - poderíamos usar *custom properties*. Este é um exemplo relativamente simples, mas pode ser muito mais útil se tivermos um grid complexo. E a técnica também pode se aplicar a coisas como tamanho de uma faixa ou posicionamento de um item.

# Vendor Prefixes

Algumas propriedades (como `clip-path`) ainda exigem *vendor prefixes* (prefixos de fornecedores) em alguns navegadores - embora, felizmente, esse número esteja diminuindo. Se você precisar escrever um *vendor prefix* e desejar alterar o valor da propriedade, também precisará alterá-lo na propriedade prefixada. Com *custom properties*, poderíamos escrever:

```css
.some-element {
  --clip: polygon(0 0, 100% 0, 50% 100%, 0 100%);

  -webkit-clip-path: var(--clip);
  clip-path: var(--clip);
}
```

Agora, só temos um lugar que precisamos mudar!

# Finalizando

Esses estão longe de serem os únicos usos para *custom properties*, mas são aqueles que eu normalmente encontro no meu fluxo de trabalho e podem ajudar a tornar seu código mais eficiente e sustentável. Sem dúvida, você descobrirá muitos outros usos por conta própria!

# Créditos

- [7 Uses for CSS Custom Properties](https://css-irl.info/7-uses-for-css-custom-properties/), escrito originalmente por [Michelle Barker](https://twitter.com/MicheBarks).