Eu estou tentando usar variáveis CSS na consulta de mídia e ele não funciona.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Eu estou tentando usar variáveis CSS na consulta de mídia e ele não funciona.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Respostas:
Das especificações ,
A
var()
função pode ser usada no lugar de qualquer parte de um valor em qualquer propriedade em um elemento. ovar()
função não pode ser usada como nomes de propriedades, seletores ou qualquer outra coisa além de valores de propriedades. (Isso geralmente produz uma sintaxe inválida ou um valor cujo significado não tem conexão com a variável.)
Portanto, não, você não pode usá-lo em uma consulta de mídia.
E isso faz sentido. Porque você pode definir, --mobile-breakpoint
por exemplo :root
, para , ou seja, o <html>
elemento e, a partir daí, ser herdado para outros elementos. Mas uma consulta de mídia não é um elemento, ela não herda de<html>
, portanto, não pode funcionar.
Não é isso que as variáveis CSS estão tentando realizar. Você pode usar um pré-processador CSS.
Como a Oriol respondeu , atualmente, o nível 1 das variáveis CSS var()
não pode ser usado em consultas de mídia . No entanto, houve desenvolvimentos recentes que abordarão esse problema. Dentro de alguns anos, quando o Módulo 1 de variáveis de ambiente CSS for padronizado e implementado, poderemos usarenv()
variáveis em consultas de mídia em todos os navegadores modernos.
Se você ler a especificação e tiver alguma preocupação, ou se desejar expressar seu suporte ao caso de uso de consulta de mídia, ainda poderá fazê-lo no GitHub w3c / csswg-draft # 1693 ou em qualquer problema de CSS GitHub prefixado com "[ css-env-1] " .
Resposta original 09/11/2017 : Recentemente, o Grupo de Trabalho CSS decidiu que o nível de variáveis 2 do CSS oferecerá suporte ao uso de variáveis de ambiente definidas pelo usuário env()
e tentará torná-las válidas em consultas de mídia . O Grupo resolveu isso depois que a Apple propôs propriedades padrão de agente de usuário pela primeira vez , pouco antes do anúncio oficial do iPhone X em setembro de 2017 (consulte também o WebKit: “Criando sites para o iPhone X” de Timothy Horton ). Outros representantes do navegador concordaram que seriam geralmente úteis em muitos dispositivos, como telas de televisão e impressão a tinta com bordas de sangria. ( env()
costumava ser chamadoconstant()
, mas que agora foi descontinuado. Você ainda pode ver artigos que se referem ao nome antigo, como este artigo de Peter-Paul Koch .) Depois de algumas semanas, Cameron McCormack, da Mozilla, percebeu que essas variáveis de ambiente seriam utilizáveis em consultas de mídia e Tab Atkins, Jr. o Google então percebeu que variáveis de ambiente definidas pelo usuário seriam especialmente úteis como variáveis raiz globais e não substituíveis, utilizáveis em consultas de mídia. Agora, Dean "Dino" Jackson, da Apple, se juntará a Atkins na edição do Nível 2.
Você pode se inscrever para receber atualizações sobre esse assunto na w3c/csswg-drafts
edição 1693 do GitHub . (Para detalhes históricos especialmente relevantes, expanda os logs de reunião incorporados nas resoluções do CSSWG Meeting Bot e procure por "MQ", que significa "consultas de mídia".)
Pretendo atualizar esta questão no futuro, quando ocorrerem mais desenvolvimentos. O futuro é emocionante.
Atualização 2018-02-08 : O
Safari Technology Preview 49 adicionou suporte para análise calc()
em consultas de mídia, o que pode ser um prelúdio para o suporte a env()
elas também.
Atualização 2018-04-27 : a equipe do Chromium no Google decidiu começar a trabalhar env()
. Em resposta, a Atkins começou a especificar env()
em um rascunho padrão não oficial: o Módulo de Variáveis de Ambiente CSS Nível 1 . (Veja seu comentário no GitHub em w3c / csswg-drafts # 1693 e seu comentário em w3c / csswg-drafts # 1817. ) O rascunho chama variáveis nas consultas de mídia como um caso de uso explícito:
Como as variáveis de ambiente não dependem do valor de algo extraído de um elemento específico, elas podem ser usadas em locais onde não há elemento óbvio para extrair, como em
@media
regras, nas quais avar()
função não seria válida.
Se você ler a especificação e tiver alguma preocupação, ou se desejar expressar seu suporte ao caso de uso de consulta de mídia, ainda poderá fazê-lo no GitHub w3c / csswg-draft # 1693 ou em qualquer problema de CSS GitHub prefixado com "[ css-env-1] " .
Atualização 2019-07-06 : O trabalho continua com as especificações. O problema do GitHub nº 2627 e o do GitHub nº 3578 são dedicados a variáveis ambientais personalizadas em consultas de mídia.
No entanto, o que você PODE fazer é @media consultar sua instrução: root!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
Funciona totalmente no Chrome, Firefox e Edge pelo menos nas versões de produção mais recentes a partir desta publicação.
var
, também pode ser usado em cálculos em outros locais css
, isso ainda exige colocar o "valor mágico" (aqui, 479px) em dois lugares: a consulta de mídia e uma declaração var.
Aparentemente, não é possível usar variáveis CSS nativas como essa. É uma das limitações .
Uma maneira inteligente de usá-lo é alterar suas variáveis na consulta de mídia, impactando todo o seu estilo. Eu recomendo este artigo .
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
Uma maneira de conseguir o que você deseja é usar o pacote npm postcss-media-variables
.
Se você está bem com o uso de pacotes npm, pode dar uma olhada no documentatoin para o mesmo aqui
Exemplo
/* input */
:root {
--min-width: 1000px;
--smallscreen: 480px;
}
@media (min-width: var(--min-width)) {}
@media (max-width: calc(var(--min-width) - 1px)) {}
@custom-media --small-device (max-width: var(--smallscreen));
@media (--small-device) {}
Como você pode ler outras respostas, ainda não é possível fazer isso.
Alguém mencionou variáveis de ambiente personalizadas (semelhantes às variáveis de CSS personalizadas em env()
vez de var()
), e o princípio é sólido, embora ainda existam 2 problemas principais:
Você pode usar o JavaScript para alterar o valor das consultas de mídia e configurá-lo para o valor de uma variável css.
// get value of css variable
getComputedStyle(document.documentElement).getPropertyValue('--mobile-breakpoint'); // '642px'
// search for media rule
var mediaRule = document.styleSheets[i].cssRules[j];
// update media rule
mediaRule.media.mediaText = '..'
Escrevi um pequeno script que você pode incluir em sua página. Ele substitui todas as regras de mídia por um valor de 1px
com o valor da variável css --replace-media-1px
, regras por valor 2px
com --replace-media-2px
e assim por diante. Isso funciona para as consultas de mídia with
, min-width
, max-width
, height
, min-height
e max-height
mesmo quando eles estão conectados usando and
.
JavaScript:
function* visitCssRule(cssRule) {
// visit imported stylesheet
if (cssRule.type == cssRule.IMPORT_RULE)
yield* visitStyleSheet(cssRule.styleSheet);
// yield media rule
if (cssRule.type == cssRule.MEDIA_RULE)
yield cssRule;
}
function* visitStyleSheet(styleSheet) {
try {
// visit every rule in the stylesheet
var cssRules = styleSheet.cssRules;
for (var i = 0, cssRule; cssRule = cssRules[i]; i++)
yield* visitCssRule(cssRule);
} catch (ignored) {}
}
function* findAllMediaRules() {
// visit all stylesheets
var styleSheets = document.styleSheets;
for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++)
yield* visitStyleSheet(styleSheet);
}
// collect all media rules
const mediaRules = Array.from(findAllMediaRules());
// read replacement values
var style = getComputedStyle(document.documentElement);
var replacements = [];
for (var k = 1, value; value = style.getPropertyValue('--replace-media-' + k + 'px'); k++)
replacements.push(value);
// update media rules
for (var i = 0, mediaRule; mediaRule = mediaRules[i]; i++) {
for (var k = 0; k < replacements.length; k++) {
var regex = RegExp('\\((width|min-width|max-width|height|min-height|max-height): ' + (k+1) + 'px\\)', 'g');
var replacement = '($1: ' + replacements[k] + ')';
mediaRule.media.mediaText = mediaRule.media.mediaText.replace(regex, replacement);
}
}
CSS:
:root {
--mobile-breakpoint: 642px;
--replace-media-1px: var(--mobile-breakpoint);
--replace-media-2px: ...;
}
@media (max-width: 1px) { /* replaced by 642px */
...
}
@media (max-width: 2px) {
...
}