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 (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):
1 2 3 4 5 6 |
CSS.registerProperty({ name: '--colorPrimary', syntax: '<color>', initialValue: 'magenta', inherits: false }); |
Direto no CSS (a partir do Chromium 85):
1 2 3 4 5 |
@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!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.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.
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:
1 2 3 4 5 6 7 8 |
/* 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%
:
1 2 3 4 5 6 |
@supports (background: paint(something)) { .post:hover, .post:focus { --gradPoint: 100%; } } |
Agora sim acontece a transição suave de degradê.
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: