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 */
}
| Regra | Detalhe |
|---|---|
| Nome | Começa com --, seguido de letras, dígitos, - ou _. Diferencia maiúsculas: --Brand não é --brand. |
| Valor | Quase qualquer coisa: uma cor, um comprimento, uma lista, uma string. Só é verificado quando é usado. |
| Onde declarar | Em qualquer regra. :root para globais, o seletor de um componente para valores locais. |
| Herança | Custom properties são herdadas, então um filho enxerga os valores dos ancestrais. |
Onde var() funciona | Só 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 CSS | Variáveis Sass | |
|---|---|---|
| Sintaxe | --brand: #2563eb; e var(--brand) | $brand: #2563eb; |
| Quando é resolvida | No navegador, ao vivo | No build, some do resultado |
| Muda por elemento | Sim, por herança | Não |
| Muda com uma classe ou media query | Sim | Não |
| Muda pelo JavaScript | Sim | Não |
| Uso em seletores ou condições de mídia | Não | Sim |
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--branddeclarada como-brandnã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 depoismargin: var(--gap)pxnão produz10px. Usecalc(var(--gap) * 1px)ou guarde10px. - Declarar no elemento errado. Uma variável declarada em
.cardnã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.