@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 CSS e dão aos desenvolvedores acesso ao modelo de objeto CSS. 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 navegador forneç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.

Essa API aumenta o desempenho das suas propriedades personalizadas do CSS (também conhecidas como variáveis do CSS) dando a elas um significado semântico (definido por uma sintaxe) e até valores padrão, permitindo o teste do 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 é por meio de CSS.registerProperty() em JavaScript, mas em navegadores compatíveis, você pode 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 de fallback) 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 personalizado)

A configuração de uma sintaxe permite que o navegador faça a verificação de tipo de propriedades personalizadas. Isso traz 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.

Ao usar uma propriedade personalizada com uma sintaxe de "número", o gradiente à esquerda mostra uma transição suave entre os valores das paradas. 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 permitirá a transição suave do gradiente.

Bordas de gradiente com transição suave. Confira a demonstração no Glitch

Conclusão

A regra @property torna uma tecnologia interessante 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.