Variáveis CSS: por que é importante?

Variáveis CSS, conhecidas como propriedades personalizadas de CSS, chegam ao Chrome 49. Podem ser úteis para reduzir a repetição no CSS e também para efeitos poderosos de tempo de execução, como troca de temas e possivelmente extensão/polyfilling de futuros recursos CSS.

Desordem de CSS

Ao projetar um aplicativo, é uma prática comum separar um conjunto de características cores que serão reutilizadas para manter a aparência do app consistente. Infelizmente, repetir esses valores de cor repetidamente no CSS é não só uma tarefa, mas também propensa a erros. Se, em algum momento, uma das cores precisa ser alterado, você pode jogar com cautela e "encontrar e substituir" tudo, mas em um projeto grande o suficiente isso pode facilmente ser perigoso.

Recentemente, muitos desenvolvedores recorreram a pré-processadores de CSS, como SASS, ou MENOS que resolvam esse problema com o uso de variáveis de pré-processador. essas ferramentas aumentaram muito a produtividade dos desenvolvedores, têm uma grande desvantagem: são estáticos e não podem ser alterado no tempo de execução. A possibilidade de alterar variáveis no ambiente de execução não apenas abre a porta para coisas como temas de aplicativos dinâmicos, mas também tem ramificações para o design responsivo e a possibilidade do polyfill de futuros CSS atributos de machine learning. Com o lançamento do Chrome 49, esses recursos agora estão disponíveis em o formato de propriedades personalizadas de CSS.

Propriedades personalizadas em poucas palavras

As propriedades personalizadas adicionam dois novos recursos à caixa de ferramentas de CSS:

  • A capacidade de um autor atribuir valores arbitrários a uma propriedade com um nome escolhido pelo autor.
  • A função var(), que permite que um autor use esses valores em outras propriedades.

Este é um exemplo rápido para demonstrar

:root {
    --main-color: #06c;
}

#foo h1 {
    color: var(--main-color);
}

--main-color é uma propriedade personalizada definida pelo autor com um valor de #06c. Observação que todas as propriedades personalizadas começam com dois traços.

A função var() recupera e substitui a si mesma pela propriedade personalizada. , resultando em color: #06c; desde que a propriedade personalizada seja definida em algum lugar da folha de estilo, ela deve estar disponível para a função var.

A sintaxe pode parecer um pouco estranha no início. Muitos desenvolvedores perguntam: "Por que não basta usar $foo para nomes de variáveis?" A abordagem foi escolhida especificamente para ser o mais flexível possível e potencialmente permitir macros $foo no futuro. Para o histórico, leia esta postagem. de um dos autores das especificações, Tab Atkins.

Sintaxe da propriedade personalizada

A sintaxe de uma propriedade personalizada é simples.

--header-color: #06c;

As propriedades personalizadas diferenciam maiúsculas de minúsculas. Por isso, --header-color e --Header-Color são propriedades personalizadas diferentes. Embora possam parecer simples no valor nominal, a sintaxe permitida para propriedades personalizadas é na verdade muito permissivo. O exemplo a seguir é uma propriedade personalizada válida:

--foo: if(x > 5) this.width = 10;

Embora não seja útil como variável, porque seria inválido em qualquer propriedade normal, ele poderia ser lido e usado com JavaScript em no ambiente de execução. Isso significa que propriedades personalizadas têm o potencial de abrir todos os tipos de técnicas interessantes atualmente que não são possíveis com os pré-processadores de CSS atuais. Então, Se você estiver pensando "Bocejo, eu tenho SASS, então quem se importa...", dê uma segunda olhada! Essas não são as variáveis com as quais você está acostumado.

A cascata

As propriedades personalizadas seguem regras em cascata padrão, para que você possa definir as mesmas em diferentes níveis de especificidade

:root { --color: blue; }
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }
<p>I inherited blue from the root element!</p>
<div>I got green set directly on me!</div>
<div id="alert">
    While I got red set directly on me!
    <p>I’m red too, because of inheritance!</p>
</div>

Isso significa que você pode usar propriedades personalizadas nas consultas de mídia para ajudar com design responsivo. Um caso de uso pode ser expandir a margem em torno seus principais elementos de divisão conforme o tamanho da tela aumenta:

:root {
    --gutter: 4px;
}

section {
    margin: var(--gutter);
}

@media (min-width: 600px) {
    :root {
    --gutter: 16px;
    }
}

É importante ressaltar que o snippet de código acima não é possível usando os pré-processadores de CSS atuais, que são incapazes de definir variáveis dentro de mídias consultas. Essa habilidade desbloqueia muito potencial!

Também é possível ter propriedades personalizadas que derivam o valor de outros propriedades personalizadas. Isso pode ser extremamente útil para a aplicação de temas:

:root {
    --primary-color: red;
    --logo-text: var(--primary-color);
}

Função var()

Para recuperar e usar o valor de uma propriedade personalizada, será necessário usar o método função var(). A sintaxe da função var() é semelhante a esta:

var(<custom-property-name> [, <declaration-value> ]? )

Em que <custom-property-name> é o nome de uma propriedade personalizada definida pelo autor. como --foo, e <declaration-value> é um valor de substituição a ser usado quando o propriedade personalizada referenciada não é válida. Os valores substitutos podem ser separados por vírgula lista, que será combinada em um único valor. Por exemplo, var(--font-stack, "Roboto", "Helvetica"); define um substituto de "Roboto", "Helvetica". Manter em Lembre-se de que valores abreviados, como os usados para margem e preenchimento, não são separados por vírgula. Assim, um substituto apropriado para padding ficaria assim.

p {
    padding: var(--pad, 10px 15px 20px);
}

Com esses valores de substituição, o autor de um componente pode escrever estilos defensivos para seu elemento:

/* In the component’s style: */
.component .header {
    color: var(--header-color, blue);
}
.component .text {
    color: var(--text-color, black);
}

/* In the larger application’s style: */
.component {
    --text-color: #080;
    /* header-color isn’t set,
        and so remains blue,
        the fallback value */
}

Essa técnica é especialmente útil para a aplicação de temas em componentes da Web que usam sombra DOM, já que propriedades personalizadas podem atravessar limites de sombra. Um autor de componente da Web pode criar um design inicial usando valores substitutos e expor os "ganchos" dos temas na forma de propriedades personalizadas.

<!-- In the web component's definition: -->
<x-foo>
    #shadow
    <style>
        p {
        background-color: var(--text-background, blue);
        }
    </style>
    <p>
        This text has a yellow background because the document styled me! Otherwise it
        would be blue.
    </p>
</x-foo>
/* In the larger application's style: */
x-foo {
    --text-background: yellow;
}

É preciso ter cuidado ao usar var(). As variáveis não podem ser nomes de propriedades. Por exemplo:

.foo {
    --side: margin-top;
    var(--side): 20px;
}

No entanto, isso não é equivalente a definir margin-top: 20px;. Em vez disso, segunda declaração é inválida e gerada como um erro.

Da mesma forma, não é possível criar (ingenuamente) um valor em que parte dele é fornecida pela uma variável:

.foo {
    --gap: 20;
    margin-top: var(--gap)px;
}

Novamente, isso não é equivalente a definir margin-top: 20px;. Para criar você precisa de outra coisa: a função calc().

Criar valores com calc()

Se você nunca trabalhou com ela, a função calc() é um pouco simples ferramenta que permite realizar cálculos para determinar valores de CSS. Ele é compatível com todos os navegadores mais recentes e pode ser combinado com com propriedades personalizadas para criar novos valores. Exemplo:

.foo {
    --gap: 20;
    margin-top: calc(var(--gap) * 1px); /* niiiiice */
}

Como trabalhar com propriedades personalizadas em JavaScript

Para receber o valor de uma propriedade personalizada no momento da execução, use o getPropertyValue() do objeto CSSStyleDeclaration calculado.

/* CSS */
:root {
    --primary-color: red;
}

p {
    color: var(--primary-color);
}
<!-- HTML -->
<p>I’m a red paragraph!</p>
/* JS */
var styles = getComputedStyle(document.documentElement);
var value = String(styles.getPropertyValue('--primary-color')).trim();
// value = 'red'

Da mesma forma, para definir o valor da propriedade personalizada no tempo de execução, use o Método setProperty() do objeto CSSStyleDeclaration.

/* CSS */
:root {
    --primary-color: red;
}

p {
    color: var(--primary-color);
}
<!-- HTML -->
<p>Now I’m a green paragraph!</p>
/* JS */
document.documentElement.style.setProperty('--primary-color', 'green');

Também é possível definir o valor da propriedade personalizada para se referir a outra no ambiente de execução usando a função var() na chamada para setProperty().

/* CSS */
:root {
    --primary-color: red;
    --secondary-color: blue;
}
<!-- HTML -->
<p>Sweet! I’m a blue paragraph!</p>
/* JS */
document.documentElement.style.setProperty('--primary-color', 'var(--secondary-color)');

Como as propriedades personalizadas podem se referir a outras do seu folhas de estilo, é possível imaginar como isso poderia levar a todos os tipos de informações efeitos de tempo de execução.

Suporte ao navegador

Atualmente, o Chrome 49, Firefox 42, Safari 9.1 e iOS Safari 9.3 são compatíveis com a propriedades.

Demonstração

Experimente o amostra para conhecer todas as técnicas interessantes que você pode aproveitar agora a propriedades personalizadas.

Leitura adicional

Se quiser saber mais sobre as propriedades personalizadas, Philip Walton, a equipe do Google Analytics escreveu por que ele está animado com as propriedades personalizadas. e você pode acompanhar o progresso deles em outros navegadores chromestatus.com.