Variáveis no CSS

Sim, meus amigos, os browsers estão começando a ter suporte a variáveis no CSS! O Firefox já oferece o suporte nativamente, enquanto chrome tem suporte em sua versão canary. Confira a tabela no caniuse e mantenha-se atualizado.

:root

Antes de abordarmos as variáveis propriamente ditas, vejamos o :root. Trata-se de uma pseudo-class que representa o topo da árvore do documento, ou seja, o html. A diferença aqui é que o seletor html tem um pouco menos de especificidade que o seletor :root. Além disto, :root também representará o topo da árvore em documentos xml, svg, etc.

Sintaxe

Para que uma variável funcione e seja acessível em todos os níveis de seu css, utilizamos o :root.

A sintaxe é muito simples, basicamente acrescente um par de - a algum nome válido de variável, :, e então o valor desta variável, assim:

:root {
  --bg-color: rgba(0, 0, 0, .7);
}

Para acessarmos o valor de uma variável, precisamos evoca-la utilizando var().

.some-element {
  background: var(--bg-color);
}

Escopo

Como citei antes, utilizamos o :root para termos uma variável totalmente acessível, mas as variáveis no css suportam escopo.

Desta forma:

.parent-el { --size: 4rem; min-height: var(--size); }

.parent-el .some-child-el { width: var(--size); /* funciona normalmente */ }

.some-other-el { width: var(--size); /* não funcionará */ }

Muito legal, não? Podemos inclusive fazer nested variables.

.grand-parent-el { --size: 4rem; }

.grand-parent-el .parent-el { --color: red; }

.grand-parent-el .parent-el .some-child-el { width: var(--size); color: var(--color); }

Outra coisa interessante é que podemos utilizar pseudo-elements da mesma maneira, hierarquicamente.

.parent-el:after {
  width: var(--size);
}

Porém, caso queira adicionar uma variável ao content do pseudo-element, ele precisa ser do tipo string.

:root {
  --text: "something";
  --size: 30px;
}
.some-element:before {
  /* funciona */
  content: var(--text);
}
.some-element:after {
  /* não funciona pois não é uma string */
  content: var(--size);
}

calc + variables

Podemos avançar mais e fazer alguns experimentos um pouco mais complexos, utilizando o calc.

O calc permite que um valor seja calculado “sob demanda”, diretamente pelo css. Por exemplo:

.some-selector {
  width: calc(100% - 50px);
}

Agora, vislumbre a possibilidade de combinar o calc com o var! E em breve, eu espero que possamos também combinar o attr.

.some-selector {
  width: calc(100% - var(--size));
}

Uma observação importante aqui, é na forma como o calc é executado. Ao interpretar o CSS, a engine irá inicialmente armazenar a syntax, e expandi-la para coletar seu valor, apenas quando ela for usada.

Desta forma:

:root {
  --size: 150px;
}
.some-selector {
  --current-size: calc(100% - var(--size));
}
.some-other-selector {
  /* não funcionará */
  --new-size: calc(var(--current-size) / 2);
}

O que ocorre, é que calc(100% - var(--size)) será expandido para calc(100% - 150px), e então, para o valor resultante do cálculo. Até aí, tudo bem.

Mas então, no momento em que a linha calc(var(--current-size) / 2) é tratada, ela é expandida para calc(calc(100% - var(--size)) / 2)!

O problema é que não há suporte a nested calls de calc. Ainda existem discussões no grupo do CSS na W3C, conversando sobre se calc deveria suportar chamadas aninhadas ou não.

Concluindo

O que achou das variáveis no css? Deixe seu comentário e vamos falar do assunto!

Veja também algumas referências:

Autor(a)

  Posts