@property: como atribuir superpoderes às variáveis CSS

CSS Houdini é um termo abrangente que abrange um conjunto de APIs de baixo nível que expõem partes do mecanismo de renderização do CSS e dão acesso ao modelo de objetos do CSS aos desenvolvedores. Essa é uma grande mudança para o ecossistema do CSS, já que permite que os desenvolvedores digam ao navegador como ler e analisar CSS personalizado sem esperar que os fornecedores de navegadores ofereçam suporte integrado a esses recursos. Que demais!

Uma das adições mais interessantes ao CSS no guarda-chuva do Houdini é a API Properties and Values.

Esta API potencializa suas propriedades personalizadas CSS (também comumente chamadas de variáveis ​​CSS), atribuindo a elas significado semântico (definido por uma sintaxe) e até mesmo valores alternativos, permitindo testes de CSS.

Como gravar propriedades personalizadas do Houdini

Confira um exemplo de como definir uma propriedade personalizada (pense em uma variável CSS), mas agora com uma sintaxe (tipo), um valor inicial (padrão) e um booleano de herança (ele herda o valor do pai ou não?). A maneira atual de fazer isso é usando CSS.registerProperty() no JavaScript, mas em navegadores compatíveis, é possível usar @property:

Arquivo JavaScript separado (Chromium 78)
CSS.registerProperty({
  name: '--colorPrimary',
  syntax: '<color>',
  initialValue: 'magenta',
  inherits: false
});
Incluído no arquivo CSS (Chromium 85)
@property --colorPrimary {
  syntax: '<color>';
  initial-value: magenta;
  inherits: false;
}

Agora é possível acessar --colorPrimary como qualquer outra propriedade personalizada do CSS, por meio de var(--colorPrimary). No entanto, a diferença aqui é que --colorPrimary não é lido apenas como uma string. Ele tem dados!

Valores substitutos

Como qualquer outra propriedade personalizada, é possível receber (usando var) ou definir (gravar/reescrever) valores, mas com propriedades personalizadas do Houdini, se você definir um valor falso ao substituir, o mecanismo de renderização do CSS vai enviar o valor inicial (o valor padrão) em vez de ignorar a linha.

Considere o exemplo abaixo. A variável --colorPrimary tem um initial-value de magenta. Mas o desenvolvedor atribuiu o valor inválido "23". Sem @property, o analisador de CSS ignoraria o código inválido. Agora, o analisador volta para magenta. Isso permite substituições e testes reais no CSS. Tudo pronto.

.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, 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 (uma string de identificador personalizada)

A configuração de uma sintaxe permite que o navegador faça a verificação de tipo de propriedades personalizadas. Isso tem muitos benefícios.

Para ilustrar esse ponto, vou mostrar como animar um gradiente. No momento, não há como animar (ou interpolar) suavemente entre valores de gradiente, já que cada declaração de gradiente é analisada como uma string.

Usando uma propriedade personalizada com uma sintaxe "number", o gradiente à esquerda mostra uma transição suave entre os valores de parada. O gradiente à direita usa uma propriedade personalizada padrão (sem sintaxe definida) e mostra uma transição abrupta.

Neste exemplo, a porcentagem de parada do gradiente está sendo animada de um valor inicial de 40% para um valor final de 100% por uma interação de passar o cursor. Você vai notar uma transição suave da cor do gradiente superior para baixo.

O navegador à esquerda oferece suporte à API Houdini Properties and Values, permitindo uma transição suave de degraus de gradiente. O navegador à direita não. O navegador sem suporte só consegue entender essa mudança como uma string que vai do ponto A ao ponto B. Não há oportunidade de interpolar os valores. Portanto, você não vê essa transição suave.

No entanto, se você declarar o tipo de sintaxe ao escrever propriedades personalizadas e usar essas propriedades para ativar a animação, a transição vai aparecer. É possível instanciar a propriedade personalizada --gradPoint desta forma:

@property --gradPoint {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 40%;
}

Quando chegar a hora de animar, atualize o valor do 40% inicial para 100%:

.post:hover,
.post:focus {
  --gradPoint: 100%;
}

Isso vai permitir a transição suave do gradiente.

A transição suave das bordas de gradiente. Confira a demonstração no CodePen

Conclusão

A regra @property torna uma tecnologia incrível ainda mais acessível, permitindo que você escreva CSS semanticamente significativo no próprio CSS. Para saber mais sobre o CSS Houdini e a API Properties and Values, confira estes recursos:

Foto de Cristian Escobar no Unsplash.