# @property: variáveis CSS com superpoderes

> @property CSS: propriedades customizadas tipadas e poderosas. Nova feature revolucionária para custom properties com tipos, valores iniciais e herança. Use!

URL: https://dpw.dev/css/property-css/  
Publicado em: 2020-07-23  
Categoria: css  
Autor: Tárcio Zemel

**CSS Houdini** é um termo abrangente que contempla um conjunto de APIs de que expõem partes do mecanismo de renderização de CSS, permitindo acesso ao CSS Object Model (CSSOM). Uma de suas grandes sensações é a **Properties and Values API**, com sua a diretiva **@property**.

Essa é uma grande mudança para o ecossistema CSS que permite instruir o navegador sobre como ler e analisar (_parse_) CSS personalizado sem esperar que _vendors_ implementem nativamente novos recursos.

Uma das adições mais incríveis ao Houdini é a [Properties and Values API](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Properties_and_Values_API) (API de Propriedades e Valores). Essa API aprimora **CSS Custom Properties** (também conhecido como **Variáveis CSS**), dando a elas significado semântico (definido por uma sintaxe) e até valores de _fallback_.

## Custom Properties com Houdini

Eis um exemplo de configuração de uma propriedade personalizada (pense: variável CSS), mas agora com uma sintaxe (_type_), valor inicial (_fallback_) e herança booleana (se herda o valor do pai ou não).

A maneira atual de fazer isso é através de `CSS.registerProperty()` em JavaScript, mas no Chromium 85 e posterior, a sintaxe `@property` será suportada diretamente no CSS.

JavaScript à parte (Chromium 78):

```
CSS.registerProperty({
  name: '--colorPrimary',
  syntax: '<color>',
  initialValue: 'magenta',
  inherits: false
});
```

Direto no CSS (a partir do Chromium 85):

```
@property --colorPrimary {
  syntax: '<color>';
  initial-value: magenta;
  inherits: false;
}
```

Agora é possível acessar `--colorPrimary` como qualquer outra propriedade customizada de CSS, via `var(--colorPrimary)`.

A diferença é que `--colorPrimary` não é apenas lido como uma string: tem dados!

## Fallbacks

Como em qualquer outra propriedade customizada, é possível obter (usando `var()`) ou definir (gravar/reescrever) valores, mas com as custom properties do Houdini, se se definir um valor errôneo, ao substituí-lo, o mecanismo de renderização de CSS enviará o valor inicial (seu valor de _fallback_) ao invés de ignorar a linha.

No exemplo abaixo, a variável `--colorPrimary` possui um valor inicial `magenta`, mas se atribuiu o valor inválido "23". Sem `@property`, o parser de CSS ignoraria o código inválido.

Agora, o parser volta a `magenta`. Isso permite verdadeiros _fallbacks_ e testes no CSS!

```scss
.card {
  background-color: var(--colorPrimary); /* magenta */
}

.highlight-card {
  --colorPrimary: yellow;
  background-color: var(--colorPrimary); /* yellow */
}

.another-card {
  --colorPrimary: 23;
  background-color: var(--colorPrimary); /* magenta */
}
```

## Sintaxe

Com o recurso de sintaxe (`syntax`), agora é possível escrever CSS semântico especificando um tipo.

Os tipos atuais permitidos incluem:

- `length`
- `number`
- `percentage`
- `length-percentage`
- `color`
- `image`
- `url`
- `integer`
- `angle`
- `time`
- `resolution`
- `transform-list`
- `transform-function`
- `custom-ident` (string de identificador personalizado)

Definir uma sintaxe permite que o navegador verifique (_type-check_) as propriedades personalizadas. Isso traz muitos benefícios.

Para ilustrar esse ponto, veja como animar um degradê. Atualmente, não há como animar suavemente (ou interpolar) entre valores de degradê, pois cada declaração é analisada (_parsed_) como uma _string_.

<figure>

![CSS @property: gif animado mostrando bordas com degradê em 2 cenários, uma funciona corretamente e outra não.](/images/blog/property-css/property-css-degrades1.gif)

<figcaption>

Usando _custom property_ com uma sintaxe "number", o degradê à esquerda mostra uma transição suave entre os _stop values_. O degradê à direita usa uma _custom property_ padrão (sem _syntax_ definida), apresentando uma transição abrupta.

</figcaption>

</figure>

Neste exemplo, a porcentagem do _stop_ do degradê está sendo animada de um valor inicial de `40%` para um valor final de `100%` por meio de uma interação instantânea.

O navegador à esquerda suporta Properties and Values API, permitindo uma transição suave de gradiente. O navegador à direita não.

O navegador não compatível apenas consegue entender essa alteração como uma sequência que vai do ponto A ao ponto B, não conseguindo interpolar os valores e, portanto, não apresentando a transição suave.

No entanto, se se declarar o tipo de sintaxe (_syntax type_) ao escrever propriedades personalizadas e usá-las para ativar a animação, ocorrerá a transição.

É possível instanciar a propriedade customizada `--gradPoint` da seguinte maneira:

```
/* Verifica suporte a Houdini & registra variável CSS */
@supports (background: paint(something)) {
  @property --gradPoint {
    syntax: '<percentage>';
    inherits: false;
    initial-value: 40%;
  }
}
```

Então, na hora de animar, atualiza-se o valor dos `40%` iniciais para `100%`:

```scss
@supports (background: paint(something)) {
  .post:hover,
  .post:focus {
    --gradPoint: 100%;
  }
}
```

Agora sim acontece a transição suave de degradê.

<figure>

![CSS @property: gif animado mostrando todas as bordas com degradê funcionando perfeitamente.](/images/blog/property-css/property-css-degrades-smooth-borders.gif)

<figcaption>

Transição suave de bordas com degradê. [Veja a demonstração em ação](https://glitch.com/~houdini-gradient-borders).

</figcaption>

</figure>

## Conclusão

A diretiva `@property` dá superpoderes às Variáveis CSS, tornando uma tecnologia interessante e muito útil ainda melhor, permitindo que se escreva CSS semanticamente significativo no próprio CSS!

Para saber mais sobre CSS Houdini e a Properties and Values API, confira estes recursos:

- [Is Houdini Ready Yet?](http://ishoudinireadyyet.com/)
- [MDN Houdini Reference](https://developer.mozilla.org/en-US/docs/Web/Houdini)
- [Smarter custom properties with Houdini's new API](https://web.dev/css-props-and-vals/)
- [Houdini CSSWG Issue Queue](https://github.com/w3c/css-houdini-drafts/issues)

---

Fonte: [dpw - desenvolvimento para web](https://dpw.dev/) (pt-BR).
Guia para agentes: https://dpw.dev/llms.txt
Índice completo: https://dpw.dev/sitemap-index.xml
Feed: https://dpw.dev/rss.xml
