Menu

Variáveis CSS: custom properties, :root e var()

As variáveis CSS (custom properties) guardam um valor uma vez e o reaproveitam com var(). Veja como declará-las no :root, definir escopo e sobrescrever, dar valores padrão, trocar temas com JavaScript e fugir da armadilha do valor inválido.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Declarar e usar uma variável CSS

Uma variável CSS, oficialmente uma custom property, é uma propriedade cujo nome começa com --. Declare uma vez, normalmente no :root para a página toda herdar, e leia em qualquer lugar com var().

Mude --brand para #16a34a e a borda do card e o botão mudam juntos. A ideia é exatamente essa: um valor, um lugar para mudar. As variáveis também se combinam com calc(), como mostra o padding lateral do botão.

Sintaxe

:root {
  --name: value;         /* declare */
}

.element {
  color: var(--name);                 /* use */
  color: var(--name, #111827);        /* use, with a fallback */
  padding: calc(var(--space) * 2);    /* compute with it */
}
RegraDetalhe
NomeComeça com --, seguido de letras, dígitos, - ou _. Diferencia maiúsculas: --Brand não é --brand.
ValorQuase qualquer coisa: uma cor, um comprimento, uma lista, uma string. Só é verificado quando é usado.
Onde declararEm qualquer regra. :root para globais, o seletor de um componente para valores locais.
HerançaCustom properties são herdadas, então um filho enxerga os valores dos ancestrais.
Onde var() funcionaSó em valores de propriedades, não em seletores, nomes de propriedade ou condições de @media.

:root seleciona o elemento <html>. Ele é usado no lugar de html porque tem a especificidade de uma classe e, por convenção, indica "configurações globais".

Escopo: sobrescrever uma variável por componente

Como as variáveis são herdadas, redeclarar uma em um elemento muda o valor para esse elemento e tudo o que está dentro dele. A regra que usa a variável continua igual.

As variantes definem só uma variável, nunca a borda em si. Acrescentar uma quarta variante é uma linha.

Valores padrão (fallback)

var(--name, fallback) usa o fallback quando a variável não está definida no elemento nem em nenhum ancestral. Tudo depois da primeira vírgula é o fallback, então ele pode ter vírgulas (var(--font, Georgia, serif)) e pode ser outro var().

Mudar variáveis com JavaScript: um seletor de tema

O JavaScript pode definir uma variável em qualquer elemento com style.setProperty(). Defina em document.documentElement (o elemento <html>) e a página toda acompanha. O padrão mais comum alterna uma classe que redefine as variáveis:

Leia uma variável de volta com getComputedStyle(element).getPropertyValue('--text'). Repare que setProperty escreve um estilo inline no <html>, que vence a classe .dark; por isso, depois de apertar o segundo botão, a cor do texto fica fixa nos dois temas até o valor inline ser removido com root.style.removeProperty('--text').

Passar valores pelo HTML

Uma variável em um atributo style é o jeito mais limpo de entregar dados de cada elemento para uma folha de estilo. O design fica no CSS; o HTML só fornece um número.

calc(var(--value) * 1%) transforma o número puro em porcentagem. As variáveis também podem mudar dentro de uma media query: @media (min-width: 900px) { :root { --space: 20px; } } faz todo espaçamento que lê --space crescer em telas largas.

A armadilha do valor inválido

O navegador não tem como saber de antemão se uma variável guarda um valor válido para a propriedade que a usa. Quando não guarda, a propriedade não volta para a declaração anterior da regra. Ela fica inválida no momento do valor computado e se comporta como se fosse unset: propriedades herdadas pegam o valor do pai, as outras voltam ao valor inicial.

O texto herda 16px do <body>, e border-width volta ao valor inicial, medium, que os navegadores desenham com 3px. Sem variáveis, uma declaração inválida é descartada e a anterior sobrevive; com variáveis, já é tarde demais para isso. O fallback não ajuda quando a variável está definida mas errada: ele só vale para variável não definida.

Variáveis CSS vs variáveis Sass

Variáveis CSSVariáveis Sass
Sintaxe--brand: #2563eb; e var(--brand)$brand: #2563eb;
Quando é resolvidaNo navegador, ao vivoNo build, some do resultado
Muda por elementoSim, por herançaNão
Muda com uma classe ou media querySimNão
Muda pelo JavaScriptSimNão
Uso em seletores ou condições de mídiaNãoSim

As duas trabalham juntas: muitos projetos usam Sass para lógica de build e geram variáveis CSS para tudo o que pode ter tema.

Erros comuns

  • Esquecer os dois hífens. var(brand) e --brand declarada como -brand não funcionam.
  • Usar uma variável em uma media query. @media (min-width: var(--bp)) não é válido. Condições de mídia precisam de valores literais.
  • Esperar que a declaração anterior sobreviva a uma variável inválida. Ela não sobrevive; veja a armadilha acima.
  • Misturar unidades do jeito errado. --gap: 10; e depois margin: var(--gap)px não produz 10px. Use calc(var(--gap) * 1px) ou guarde 10px.
  • Declarar no elemento errado. Uma variável declarada em .card não é vista pelos irmãos nem pelo pai; declare valores compartilhados no :root.

Perguntas frequentes

Como declarar uma variável CSS?

Escreva, dentro de uma regra, uma propriedade cujo nome começa com dois hífens, normalmente no :root para um valor global: :root { --brand: #2563eb; }. Leia em qualquer lugar com var(--brand), por exemplo color: var(--brand);.

O que é :root no CSS?

:root é uma pseudo-classe que seleciona o elemento raiz do documento, que em uma página HTML é o <html>. As variáveis declaradas ali são herdadas por todos os elementos. Ela tem a especificidade de uma classe, então vence um seletor html simples.

Como definir um valor padrão para uma variável CSS?

Passe um segundo argumento para var(): color: var(--accent, #2563eb);. O fallback é usado quando --accent não está definida no elemento nem nos seus ancestrais. Ele não é usado quando a variável está definida com um valor inválido para a propriedade.

Como mudar uma variável CSS com JavaScript?

Chame setProperty no style de um elemento: document.documentElement.style.setProperty('--brand', '#16a34a'). Todas as regras que usam var(--brand) se atualizam na hora. Leia o valor atual com getComputedStyle(el).getPropertyValue('--brand').

Qual a diferença entre variáveis CSS e variáveis Sass?

As variáveis Sass são trocadas pelos seus valores quando a folha de estilo é compilada, então não podem mudar no navegador. As variáveis CSS vivem no navegador: são herdadas, podem variar por elemento, respondem a media queries e classes e podem ser alteradas por JavaScript.

Os nomes das variáveis CSS diferenciam maiúsculas de minúsculas?

Sim. --Brand e --brand são duas variáveis diferentes, ao contrário dos nomes de propriedades comuns como color, que não diferenciam.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR