@property — Custom Properties Tipadas e Animáveis no CSS

Como a regra @property registra variáveis CSS com tipo, valor inicial e herança definidos, permitindo animar gradientes, ângulos e outros valores que antes só eram possíveis com JavaScript.

Variáveis CSS (--*) sempre foram "burras": o navegador trata qualquer valor como texto solto, sem saber se é uma cor, um número ou um ângulo. A regra @property resolve isso registrando uma custom property com tipo definido, valor inicial e regra de herança — o que, entre outras coisas, destrava animações que antes eram impossíveis.

O problema: variáveis CSS não são animáveis

Tentar animar uma variável CSS comum não funciona como se espera. No exemplo abaixo, o navegador não sabe que --angulo é um ângulo, então ele simplesmente troca de um valor para o outro sem transição suave:

.fundo {
    --angulo: 0deg;
    background: conic-gradient(from var(--angulo), #12A8C3, #0C7A91);
    transition: --angulo 0.4s ease;
}

.fundo:hover {
    --angulo: 180deg;
}

Como o valor é tratado como texto genérico, o gradiente "pula" de uma posição para outra em vez de girar suavemente.

Como funciona o @property

Com @property, é possível registrar a variável informando um syntax (o tipo de dado), um initial-value (obrigatório, exceto quando o syntax é "*") e se ela deve herdar (inherits):

@property --angulo {
    syntax: "<angle>";
    inherits: false;
    initial-value: 0deg;
}

.fundo {
    background: conic-gradient(from var(--angulo), #12A8C3, #0C7A91);
    transition: --angulo 0.4s ease;
}

.fundo:hover {
    --angulo: 180deg;
}

Agora o navegador sabe que --angulo é um <angle> e consegue interpolar valores intermediários durante a transição, girando o gradiente de forma suave.

Tipos de syntax mais comuns

@property --cor-destaque {
    syntax: "<color>";
    inherits: true;
    initial-value: #12A8C3;
}

@property --escala {
    syntax: "<number>";
    inherits: false;
    initial-value: 1;
}

@property --largura-barra {
    syntax: "<percentage>";
    inherits: false;
    initial-value: 0%;
}

Os tipos mais usados são <color>, <number>, <percentage>, <length> e <angle>, mas também existem combinações com | (ex.: "<length> | <percentage>") e listas com +.

Exemplo prático: barra de progresso animada

@property --progresso {
    syntax: "<percentage>";
    inherits: false;
    initial-value: 0%;
}

.barra {
    width: 200px;
    height: 8px;
    background: #eee;
}

.barra::before {
    content: "";
    display: block;
    height: 100%;
    background: #12A8C3;
    width: var(--progresso);
    transition: --progresso 0.6s ease-out;
}
const barra = document.querySelector('.barra');
barra.style.setProperty('--progresso', '75%');

Como --progresso está registrada como <percentage>, a transição anima suavemente de 0% até 75%, em vez de pular direto para o valor final.

Validação de valores

Registrar o tipo também protege contra valores inválidos: se alguém tentar atribuir algo fora do syntax declarado, o navegador ignora a atribuição e usa o initial-value no lugar, em vez de aceitar qualquer texto.

Quando usar

Cuidados

O registro via @property é global na página: se duas regras registrarem a mesma propriedade com syntax diferentes, vale o último registro válido processado, então é importante manter nomes de variáveis específicos por componente. Também existe a alternativa CSS.registerProperty() via JavaScript, mas ela não é reaproveitada entre page loads como o @property em CSS.

Compatibilidade

O @property é Baseline Widely Available: tem suporte em Chrome, Edge e Opera desde 2020, Safari desde a versão 16.4 e Firefox desde a versão 128, cobrindo praticamente todos os navegadores modernos em uso.

caniuse

Conclusão

O @property transforma variáveis CSS de simples texto substituível em valores tipados que o navegador entende de verdade, destravando animações antes só possíveis com JavaScript ou truques de keyframes. É uma peça pequena, mas que muda bastante o que dá para fazer só com CSS.

Tecnologia:
css

Deixe seu Comentário!

Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.

Comentário
Nome
Email
lock Seu e-mail não será publicado.