Propriedades personalizadas

Digamos que você esteja criando alguns estilos iniciais para seu site e percebeu que está repetindo alguns dos valores no CSS. Você está usando dodgerblue como cor principal e adicionando isso a bordas de botões, texto de link, planos de fundo de cabeçalho e usando uma ferramenta de design para escolher algumas variantes desse azul para outras partes do site. Em seguida, você recebe um guia de estilo, e a cor principal agora é oklch(70% 0.15 270).

Com as propriedades personalizadas, ou variáveis CSS, é possível organizar e reutilizar valores no CSS para que seus estilos sejam mais flexíveis e fáceis de entender.

Criar propriedades

A maneira mais simples de criar uma propriedade é definir um valor em uma nova propriedade com um nome definido por você.

.card {
  --base-size: 1em;
}

Todos os nomes de propriedades precisam começar com dois traços. Isso evita que você tente usar um nome de propriedade CSS para um valor personalizado. A especificação CSS nunca vai adicionar uma propriedade que comece com dois traços.

Essa propriedade pode ser acessada com a função var(). Este exemplo define o tamanho da fonte em um .card-title para o dobro do valor --base-size.

.card .card-title {
  font-size: calc(2 * var(--base-size));
}

Usar uma propriedade personalizada

Como você viu, é possível usar o valor de uma propriedade personalizada com a função var(). É possível usar a função var() em valores, mas não em consultas de mídia. Elas são especialmente úteis como argumentos para outras funções CSS.

Substitutos

O que acontece se você tentar usar uma propriedade personalizada sem um valor definido? A função var() usa um segundo valor que será usado como um valor substituto. O valor de substituição pode até ser outra propriedade personalizada com um var() aninhado.

#my-element {
  background: var(
    --alert-variant-background,
    var(--alert-primary-background)
  );
}

Valores inválidos

Se uma propriedade personalizada for resolvida como um valor inválido, por exemplo, um valor de 1em para a propriedade background-color, outras declarações válidas nesse elemento para essa propriedade não serão usadas. Isso acontece porque o navegador não sabe se um valor é inválido até descartar outras declarações ao computar um valor. Em vez disso, o valor usado será um valor herdado ou inicial.

.content {
  background-color: blue;
}

.content.invalid {
  --length: 2rem;
  background-color: var(--length);
}

No exemplo anterior, o elemento .invalid não terá um plano de fundo azul. Em vez disso, como background-color não herda, o valor será transparent, que é o valor inicial.

Substituição e herança

Na maioria das vezes, você vai querer o comportamento padrão das propriedades personalizadas, que é a herança de valores. Quando você define um novo valor para uma propriedade, esse elemento e todos os filhos dele têm esse valor até que ele seja substituído por outro.

As propriedades personalizadas são determinadas pela cascata, então também podem ser substituídas por um seletor mais específico.

Mais controle com o @property

Uma propriedade personalizada criada ao definir um valor pode ser de qualquer tipo e é herdada. Para ter mais controle sobre uma propriedade personalizada, use a regra @property.

Nossa propriedade --base-size criada anteriormente seria equivalente a esta declaração @property.

@property --base-size {
  syntax: "*";
  inherits: true;
  initial-value: 18px;
}

O valor syntax define os tipos de valores CSS válidos para a propriedade. Se você definir um tipo diferente nessa propriedade, ela será inválida e voltará ao valor inicial ou a um valor herdado definido mais acima na cascata.

Ao criar uma propriedade personalizada usando @property, é possível desativar a herança com inherit: false. Substituir o valor de uma propriedade personalizada com a herança desativada muda o valor do elemento selecionado, mas não dos filhos dele. Isso é útil quando vários seletores têm como destino o mesmo elemento.

O initial-value define o valor da propriedade, a menos que ele seja alterado depois. A menos que a sintaxe seja *, ou seja, qualquer tipo de CSS, o @property precisa definir um initial-value. Isso garante que a propriedade sempre tenha um valor da sintaxe especificada e nunca seja indefinida.

Atualizar propriedades personalizadas com JavaScript

O valor de uma propriedade personalizada em um elemento pode ser atualizado usando JavaScript, que você pode usar para atualizar os estilos do seu site de forma dinâmica.

const element = document.getElementById("my-button");
getComputedStyle(element).setPropertyValue("--color", orange);

Este exemplo atualiza a tag de estilo no elemento #my-button. Ao inspecionar no DevTools, você verá:

<button id="my-button" style="--color: orange">Click me</button>

No exemplo anterior, você pode ver como definir propriedades personalizadas acessando dados armazenados em atributos HTML personalizados. Cada botão tem um atributo data-color com o valor de uma cor específica. A propriedade personalizada --background definida no elemento body é redefinida para o valor de data-color em qualquer botão clicado.

Você também pode usar getComputedStyle(element).getPropertyValue("--variable") para receber o valor de uma propriedade em um elemento específico. Isso pode ser útil se a lógica precisar responder a um valor em cascata.