Propriedades customizáveis a.k.a. Variáveis CSS

visualizações Publicado em: 18/07/2014 — Atualizado em: ➠ 23/06/2015 ➠ 19/04/2016

Introdução

O Módulo das CSS3 denominado CSS Custom Properties for Cascading Variables Module Level 1 (em tradução livre: Propriedades customizáveis por variáveis CSS Módulo 1) encontra-se no estágio de Candidato a Recomendação do W3C. Trata-se de uma especificação em estágio anterior ao de Recomendação do W3C, e assim sendo o suporte para as funcionalidades previstas naquela especificação já é razoável em navegadores modernos. Ver suporte atual em caniuse.com.

Para futura referência informo que este tutorial baseou-se na versão das especificações vigente à época em que foi publicada a última atualização do tutorial.

A finalidade da especificação é a de criar uma funcionalidade que consiste em um novo valor CSS primitivo denominado variável CSS para ser usado como parâmetro em uma função que retorne um valor a ser atribuido a qualquer uma das propriedades CSS, possibilitando assim o uso de variáveis nas CSS.

Propriedade CSS customizada

A sintaxe da regra CSS é conforme mostrada na figura a seguir:


sintaxe CSS

Notar que a declaração CSS compreende uma propriedade e um valor.

Valor CSS é uma grandeza ou um aspecto visual que definem quantidades ou características de uma propriedade, por exemplo: red, 2px solid blue, 2.5em, left top, etc.

Variáveis CSS permitem que se crie valor CSS que poderá ser alterado em diferentes lugares da folha de estilos alterando-se o valor da variável em um só lugar. "Propriedade CSS customizável" é a declaração de um valor para uma variável CSS conforme sintaxe que estudaremos a seguir.

A sintaxe para se criar uma variável CSS tem o formato geral --* onde o sinal asterísco (*) é um nome de livre escolha do autor, ou seja, o nome da variável, e no qual alguns caracteres não são permitidos, como por exemplo: ; # } ] ) etc.

Observe a seguir alguns exemplos mostrando a sintaxe para definição de valores de variáveis CSS. Os valores válidos para as variáveis CSS são todos os valores CSS válidos.

 --cor-um: red;
 --bordaLegal: 2px solid blue;
 --margem-linda: 2.5em;
 --POSIcAOFunDO: left top;
 --maujor: uppercase;
 --maria: 12litros; /* Inválido! litro não é uma unidade CSS */
 --comprimento: line-height; /* Inválido! line-height não é um valor CSS */ 
 --cor-texto: rgb(125, 255, 0);

Uma variável CSS destina-se a ser usada como argumento de uma função CSS denominada var() cujo valor de retorno é o valor declarado para a variável. No exemplo a seguir mostramos a sintaxe para o uso da funcão var() em uma regra CSS. Notar que usamos algumas das variáveis declaradas anteriormente.

 div {	
 border: var( bordaLegal );
 margin: var ( --margem-linda );
 text-transform: var ( --maujor );
}

Escopo das variáveis CSS

Observe o código a seguir.

 :root {
 --minha-altura: 500em;
 --minha-margem: 20px;
 --minha-cor-fundo: #0f0;
 --meu-text-align: center;
}

Observe que as variáveis foram declaradas para o seletor CSS :root. Neste caso o escopo das variáveis é o seletor :root que é a raiz do documento, ou seja a página. Diz-se que o contexto das variáveis é a página toda, ou seja, elas, variáveis, são reconhecidas e surtem efeito em regras CSS definidas para qualquer elemento da página.

Pode-se definir um contexto que contemple somente uma determinada parte da página. Por exemplo: o autor define variáveis para serem usadas e válidas somente nos elementos da página que serão marcados com uso do elemento footer. Neste caso o escopo será o elemento footer e a declaração das variáveis deverá ser conforme mostrada a seguir.

 footer {	
 --minha-cor-fundo: black;
 --minha-cor: red;
 --minha-largura: 40%;
}

As variáveis definidas conforme mostrado, surtirão efeito quando declaradas em regras CSS que têm como alvo o elemento footer e seus descendentes.

Valor default de uma variável

A especificação prevê a possibilidade de se declarar um valor default, opcional, para a variável, que deve ser passado como parâmetro para a função var() conforme mostrado no exemplo a seguir no qual a cor dos textos foi definida com uso de uma variável denominada --cor cujo valor default é a cor preta (black).

 seletor {	
 background-color: var( --cor, black );
}

Notar que a sintaxe prevê o uso de vírgula para separar os dois parâmetros da função.

Suponha uma aplicação com muitas páginas que use um componente em várias de suas páginas. No exemplo mostrado a seguir exemplificamos o uso do valor default para estilizar a propriedade CSS color (cor dos textos) da aplicação e seus componentes.

 /* Declaração da variável */ 
 .component {
  --cor-texto: green;
  /* Notar que --cor-header não foi declarada */
}

/* Regras de estilo */
 .component .header {
  color: var(--cor-header, blue); /* estiliza na cor blue */
}
 .component .text {
  color: var(--cor-texto, black); /* estiliza na cor green */
}

O código mostrado possibilita maior flexibilidade para criação de diferentes temas para os componentes. Para o tema padrão da aplicação a cor de .header, para outros temas basta declarar a variável --cor-header

Considerações gerais sobre a sintaxe para variáveis

A seguir mostramos alguns casos de sintaxe para declaração de variáveis que devem ser bem conhecidos, com a finalidade de facilitar o entendimento do que está ocorrendo com o seu código quando causarem efeitos inesperados.

Diretiva !important

A diretiva !important quando usada em um valor de variável não a invalida, contudo não altera o efeito cascata e nem a especificidade da regra CSS, ou seja, não cumpre sua finalidade.

Observe o código mostrado a seguir.

 :root {
  --cor: red!important; 
}

p { color: var(--cor); }
p { color: blue; }
a { color:  var(--cor); }

A cor dos parágrafos será blue pois a diretiva !important é ignorada e prevalece o efeito cascata. Não tivéssemos usado variáveis e declarado em lugar de color: var(--cor); color: red!important; a cor dos parágrafos seria red pois, neste caso, a diretiva !important sobrescreveria o efeito cascata.

Uma vez que a variável não é inválida a cor dos textos dos links será red.

Variáveis em lista de valores

Algumas propriedades CSS, tais como font, background, border e outras admitem uma lista de valores quando usamos a sintaxe CSS abreviada para elas.

Para essas propriedades é válido declarar a lista com uso de uma ou mais variáveis conforme mostrado no exemplo a seguir.

 :root {
  --cor: red;
  --tipo-um: solid;
  --tipo-dois: dotted;
  --tipo-tres: dashed;
}

p { border: 5px var(--tipo-dois) var(--cor); }

Os parágrafos terão uma borda vermelha, pontilhada de 5px de largura.

Sintaxe encadeada

É inválido o valor declarado com uso de uma variável combinada com uma unidade de medida CSS ou outra entidade qualquer.

O exemplo a seguir esclarece esses casos.

 :root {
  --espessura: 50;
}

p { margin: var(--espessura)px; } /* Inválido */
p { margin: calc( var(--espessura) * 1px ); } /* Válido */

Valor computado

Observe o código a seguir.

 :root {
  --bg-cor: 20px;
}

p { 
  background-color: red; 
  background-color: var(--bg-cor); 
}

Qual será a cor de fundo dos parágrafos? Se você respondeu red, é porque conhece CSS e sabe que quando uma declaração CSS está em desacordo com a sintaxe CSS ela é inválida e consequentemente ignorada e descartada pelo parser e sabe também que background-color: 20px é uma declaração inválida.

Contudo, quando se trata de propriedade customizada entra em cena um conceito denominado invalid at computed-value time (em tradução livre: inválida no momento em que for computada). Este conceito existe porque ao ser declarado um valor para a variável CSS ela será válida seja qual for o valor.

No exemplo mostrado a sintaxe --bg-cor: 20px é perfeitamente válida. O parser CSS ao "chegar" em background-color: var(--bg-cor) "descarta" as declarações anteriores para a propriedade background-color desde que tenham a mesma especificidade, o que está de acordo com as diretrizes de parseamento CSS e somente depois disso computa o valor da variável e nesse momento conclui que se trata de uma declaração inválida (invalid at computed-value time). A seguir adota o comportamento padrão das CSS atribuíndo à propriedade background-color o seu valor initial (inicial). Caso a propriedade do nosso exemplo fosse color ou outra qualquer passível de ser herdada o valor adotado seria inherit e não initial.

Portanto a cor de fundo dos parágrafos não será red e sim transparent que é o valor inicial da propriedade background-color.

Se, no código mostrado você inverter a ordem de declaração da cor de fundo, aí sim, o parágrafo terá cor red por ação do efeito cascata.

Se, no código mostrado você adotar a mesma ordem de declaração da cor de fundo, separando as declarações: a primeira para o seletor body p e a segunda para o seletor p, a cor dos parágrafos será red por ação da especificidade.

Exemplo interativo

Visite o exemplo interativo mostrado a seguir, edite as declarações e uso de variáveis e veja em tempo real os efeitos e como funcionam as variáveis CSS.

Ver pen Variáveis CSS criada pelo Maujor (@Maujor) no CodePen.

topo