Curso de CSS / Variáveis: var(), escopo, herança e fallback
Propriedades personalizadas do CSS armazenam valores reutilizáveis e são referenciadas com var() nos valores das propriedades. Seu escopo segue a cascata e a herança, e um valor de reserva do var() não recupera automaticamente um valor definido que é inválido para a propriedade receptora.
Escolha variáveis compartilhadas significativas
Se você usar a mesma cor de destaque para múltiplos botões e cartões, pode agrupá-la em uma variável significativa em vez de copiar o código da cor em cada seletor. Ao mudar a cor de destaque, se você modificar uma declaração, o lugar que referencia esse valor também muda. Se você criar variáveis, mesmo valores que são usados em apenas um lugar e não têm um papel separado, o peso de manter o controle dos nomes pode realmente aumentar.
:root {
--accent: #1d5f91;
--space-unit: .5rem;
}
.button { color: white; background: var(--accent); }
.card { border: 2px solid var(--accent); padding: calc(var(--space-unit) * 3); }
Apenas declarar uma cor no código acima não altera a tela. Propriedades como background e border precisam usar var() em seus valores para consumir a variável. Se o nome indicar a função, como --accent, em vez de fixar a cor atual, como --blue, será menos confuso ao mudar para uma cor diferente posteriormente. --accent e --Accent são nomes diferentes, então combine maiúsculas e minúsculas e a ortografia.
var() é usado para o valor de propriedades como color ou padding. Seletores ou nomes de propriedades não podem ser substituídos por variáveis, e não se pode definir com var() o limite de largura de @media (min-width: ...) ou de uma consulta de tamanho de contêiner. Escreva os pontos de quebra diretamente na instrução condicional correspondente e os diferencie dos valores aos quais variáveis podem ser aplicadas, como a cor ou o espaçamento dos elementos.
Entenda o escopo raiz, de herança e de componentes
Em um documento HTML, :root corresponde ao elemento HTML de nível superior, então é conveniente ter um valor padrão comum no documento. As propriedades personalizadas comuns -- são herdadas pelos descendentes. Essa regra descreve propriedades não registradas; o registro com @property pode definir outro comportamento de herança. Valores declarados dentro de um cartão podem ser usados pelos descendentes, como o título, mas não são passados para cartões irmãos não relacionados.
.card { --card-accent: var(--accent); }
.card.warning { --card-accent: #a63e32; }
.card { border-color: var(--card-accent); }
.card h2 { color: var(--card-accent); }
Esta regra é parte de um componente do exemplo completo abaixo. .card.warning corresponde a cartões com ambas as classes. Ganhar ou perder não é determinado pela ordem de listagem das classes HTML, mas por corresponder ao Herança, especificidade e cascata para determinar o valor. Alterar o destaque global mudará o cartão padrão, e os cartões de aviso com seu próprio destaque de cartão manterão suas cores de aviso originais.
Ao combinar variáveis com outras variáveis, também é importante de qual elemento o valor é calculado. Se --line-color: var(--accent) for calculado no elemento pai e depois passado para o filho, a cor da linha já herdada nem sempre será recalculada apenas porque o destaque é sobrescrito no filho. Valores derivados que devem seguir o destaque de seus descendentes são obviamente melhores se declarados no próprio elemento ou referenciando diretamente a variável de destaque no valor da propriedade final. Para definições de escopo e herança, veja Especificação de propriedade personalizada do CSS.
Distinga valores alternativos e valores computados inválidos
var(--notice-color, #6a3989) fornece um valor de fallback roxo quando o valor de uma variável está ausente e não pode ser usado. Mesmo que uma variável esteja definida e tenha um valor significativo em outras propriedades, como 20px, se o valor não corresponder a uma cor, a declaração de cor se torna inválida no momento do cálculo. Neste caso, você não deve esperar ser “substituído por roxo”.
| estado da variável | Resultado da declaração de cor | Cores para todo o exemplo |
|---|---|---|
| Sem --notice-color | Usando valores de fallback para var | roxo |
| --notice-color contém uma cor vermelha | Usar valores definidos | vermelho |
| --notice-color contém 20px | Regras de herança/valor inicial aplicadas porque não corresponde à cor | Como a cor é herdada, use a cor de texto verde do elemento pai. |
Como mostrado abaixo, mesmo que haja uma declaração azul primeiro na mesma regra, se o valor após a substituição da variável na segunda declaração não corresponder, ele não voltará ao primeiro azul. Após a declaração selecionada na cascata ser inválida no momento da avaliação, aplicam-se as regras de herança da cor. Na mesma situação, uma propriedade que não é herdada pode ser tratada como o valor inicial dessa propriedade. O guia de propriedades personalizadas da MDN explica a diferença entre valores de substituição e valores inválidos.
.sample {
color: #1d5f91;
color: var(--notice-color, #6a3989);
}
.sample.bad { --notice-color: 20px; }
Você também pode colocar outras variáveis no valor de fallback. Por exemplo, var(--button-accent, var(--accent, #1d5f91)) procura o valor a ser usado, começando pelo valor específico do botão, depois pelo valor comum e, finalmente, pela cor primária. No entanto, se os usos de números, comprimentos e cores estiverem misturados, o mesmo problema ocorre, então os nomes e usos das variáveis devem ser gerenciados juntos.
Combine valores e unidades com calc()
O exemplo multiplica --space-unit: .5rem por 3 para definir o padding do cartão. rem usa o tamanho da fonte da raiz, então alterar esse tamanho altera o espaçamento. Use calc() para o cálculo em vez de concatenar strings, e deixe espaços ao redor dos operadores de adição e subtração. Para mais detalhes, veja Cores e unidades: px, em, rem e porcentagens.
:root {
--space-unit: .5rem;
--space-card: calc(var(--space-unit) * 3);
}
.card { padding: var(--space-card); }
Escolha consistentemente se as variáveis incluem unidades ou apenas números. Se você inserir um valor sem unidade, como 2, na variável de comprimento, ele pode não ser adequado para aplicações que exigem unidades. Evite combinações de usos diferentes, como aplicar calc a uma variável que contenha uma cor. Para a sintaxe básica da fórmula, consulte o documento MDN calc.
Execute a comparação de escopo e fallback
Salve o seguinte código como custom-properties.html em UTF-8 e abra-o no seu navegador. Compare as cores de destaque dos dois cartões e as cores do texto das três sentenças. O significado das cores também foi escrito em letras para que os resultados não pudessem ser distinguidos apenas pela cor.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS variable scope and substitution values</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
:root { --space-unit: .5rem; --space-card: calc(var(--space-unit) * 3); --accent: #1d5f91; }
.cards { display: grid; gap: 1rem; }
.card { --card-accent: var(--accent); padding: var(--space-card); border: 2px solid var(--card-accent);
border-radius: .5rem; background: #f6f9fb; }
.card h2 { color: var(--card-accent); margin-block: 0 .5rem; }
.card p { margin: 0; }
.card.warning { --card-accent: #a63e32; }
.fallback-area { margin-block: 2rem; padding: 1rem; border: 1px solid #8a9ba7; color: #28633b; }
.sample { color: #1d5f91; color: var(--notice-color, #6a3989); }
.sample.bad { --notice-color: 20px; }
.sample.good { --notice-color: #a63e32; }
</style>
</head>
<body>
<main>
<h1>Variable scope and fallbacks</h1>
<div class="cards">
<article class="card"><h2>Basic card</h2><p>The heading and border share the same accent color.</p></article>
<article class="card warning"><h2>warning card</h2><p>The accent color changes only inside this card.</p></article>
</div>
<section class="fallback-area">
<h2>The parent's text color is green</h2>
<p class="sample missing">Undefined: purple fallback</p>
<p class="sample bad">20px: Doesn't match the color, so it inherits the green color from the parent.</p>
<p class="sample good">Defined as red: use that color</p>
</section>
</main>
</body>
</html>
- Certifique-se de que o título e a borda dos cartões básicos sejam azuis e que os cartões de aviso sejam vermelhos. As três frases abaixo são coloridas de roxo, verde e vermelho, respectivamente.
- Altere apenas a cor de destaque na raiz para
#28633b. O cabeçalho e a borda do cartão padrão devem mudar, enquanto o cartão de aviso mantém sua própria cor de aviso. Restaure a cor de destaque na raiz para#1d5f91após a verificação. - Altere apenas --space-unit por
1rem. Os espaçamentos de ambos os cartões se estendem juntos. Após a confirmação, restaure para .5rem. - Altere apenas --notice-color em .sample.bad de
20pxpara#1d5f91. A frase mudará de verde para azul. Após a confirmação, restaure para 20px. - Exclua apenas a declaração --notice-color de .sample.bad. Desta vez, um fallback roxo é usado. Compare com o resultado azul da etapa anterior e restaure a declaração original.
Diagnostique variáveis ausentes ou incorretas
- Nas ferramentas de desenvolvedor, verifique se o nome e o valor da variável realmente existem nesse elemento. Observe primeiro a ortografia, a capitalização e o escopo da declaração.
- Verifique se descendentes ou outras regras sobrescrevem a mesma variável. Pode não ser um erro um componente manter seus valores únicos mesmo que seu valor comum mude.
- Verifique se a variável é referenciada na propriedade real e se as unidades e o tipo do valor substituído estão corretos.
- Se um valor for criado através de múltiplas variáveis, verifique o elemento calculado e o valor herdado. Além disso, evite declarações que se refiram à mesma variável como elas próprias ou que tenham referências circulares.
Você pode aproveitar as variáveis distinguindo cores comuns e espaçamento do design e exceções para cada componente, e verificando os resultados antes e depois da mudança. Em vez de aumentar o número de nomes de variáveis, deixar claro quais valores são compartilhados em qual escopo é mais útil para a manutenção.




