@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 fornecem acesso ao modelo de objetos CSS. Essa é uma grande mudança para o ecossistema de CSS, porque permite que os desenvolvedores informem ao navegador como ler e analisar CSS personalizado sem esperar que os fornecedores de navegador forneçam suporte integrado para esses recursos. Muito emocionante!

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

Essa API potencializa suas propriedades personalizadas de CSS (também conhecidas como variáveis CSS) fornecendo a elas um significado semântico (definido por uma sintaxe) e até mesmo valores substitutos, o que permite o teste de CSS.

Como gravar propriedades personalizadas do Houdini

Veja um exemplo de como configurar uma propriedade personalizada (por exemplo, uma variável CSS), mas agora com uma sintaxe (tipo), valor inicial (substituto) e 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, você pode usar @property:

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

Agora você pode acessar --colorPrimary como qualquer outra propriedade personalizada de CSS usando var(--colorPrimary). No entanto, a diferença aqui é que --colorPrimary não é apenas lido como uma string. Eles contêm dados.

Valores substitutos

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

Veja o exemplo abaixo. A variável --colorPrimary tem um initial-value de magenta. No entanto, o desenvolvedor deu a ele o valor inválido "23". Sem @property, o analisador CSS ignora o código inválido. Agora, o analisador volta para magenta. Isso permite substitutos 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, é possível escrever CSS semântico especificando um tipo. Os tipos permitidos no momento incluem:

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

Definir uma sintaxe permite que o navegador verifique as propriedades personalizadas. Isso traz muitos benefícios.

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

Usando uma propriedade personalizada com uma sintaxe "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% com uma interação de passar o cursor. Você verá uma transição suave dessa cor gradiente superior para baixo.

O navegador à esquerda é compatível com a API Houdini Properties and Values, permitindo uma transição de parada do gradiente suave. O navegador à direita não. O navegador sem suporte só é capaz de entender essa mudança como uma string que vai do ponto A ao ponto B. Não há oportunidade de interpolar os valores e, assim, não é possível notar essa transição suave.

No entanto, se você declarar o tipo de sintaxe ao gravar propriedades personalizadas e usar essas propriedades para ativar a animação, a transição vai ser notada. É possível instanciar a propriedade personalizada --gradPoint da seguinte maneira:

/* Check for Houdini support & register property */
@supports (background: paint(something)) {
  @property --gradPoint {
    syntax: '<percentage>';
    inherits: false;
    initial-value: 40%;
  }
}

Em seguida, na hora de criar a animação, você pode atualizar o valor do 40% inicial para 100%:

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

Isso permite uma transição de gradiente suave.

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

Conclusão

A regra @property torna uma tecnologia interessante ainda mais acessível, permitindo que você escreva CSS semanticamente significativo dentro do 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.