Sto cercando di utilizzare le variabili CSS nella media query e non funziona.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Sto cercando di utilizzare le variabili CSS nella media query e non funziona.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Risposte:
Dalle specifiche ,
La
var()
funzione può essere utilizzata al posto di qualsiasi parte di un valore in qualsiasi proprietà di un elemento. Lavar()
funzione non può essere utilizzata come nomi di proprietà, selettori o altro oltre ai valori delle proprietà. (In questo modo in genere si produce una sintassi non valida, oppure un valore il cui significato non ha alcuna connessione con la variabile.)
Quindi no, non è possibile utilizzarlo in una query multimediale.
E questo ha senso. Perché puoi impostare --mobile-breakpoint
ad es. Su :root
, cioè l' <html>
elemento, e da lì essere ereditato da altri elementi. Ma una media query non è un elemento, non eredita da <html>
, quindi non può funzionare.
Questo non è ciò che le variabili CSS stanno cercando di realizzare. È invece possibile utilizzare un preprocessore CSS.
Come ha risposto Oriol , attualmente, le variabili CSS di livello 1 var()
non possono essere utilizzate nelle media query . Tuttavia, ci sono stati recenti sviluppi che affronteranno questo problema. Tra qualche anno, una volta standardizzato e implementato il modulo Variabili d'ambiente CSS 1 , saremo in grado di utilizzare le env()
variabili nelle query multimediali in tutti i browser moderni.
Se leggi le specifiche e hai dei dubbi, o se vuoi esprimere il tuo supporto per il caso d'uso di media query, puoi ancora farlo in GitHub w3c / csswg-drafts # 1693 o in qualsiasi problema CSS di GitHub con il prefisso "[ css-env-1] ” .
Risposta originale 09/11/2017 : di recente, il gruppo di lavoro CSS ha deciso che le variabili CSS Level 2 supporteranno l'utilizzo di variabili d'ambiente definite dall'utente env()
e proveranno a renderle valide nelle query multimediali . Il Gruppo lo ha risolto dopo che Apple ha proposto per la prima volta le proprietà standard degli user-agent , poco prima dell'annuncio ufficiale di iPhone X a settembre 2017 (vedi anche WebKit: "Progettazione di siti Web per iPhone X" di Timothy Horton ). Altri rappresentanti del browser hanno quindi concordato che sarebbero generalmente utili su molti dispositivi, come schermi televisivi e stampa a inchiostro con bordi al vivo. ( env()
era chiamatoconstant()
, ma ora è stato deprecato. Potresti ancora vedere articoli che fanno riferimento al vecchio nome, come questo articolo di Peter-Paul Koch .) Dopo alcune settimane, Cameron McCormack di Mozilla si rese conto che queste variabili d'ambiente sarebbero state utilizzabili nelle query sui media, e Tab Atkins, Jr. di Google ha quindi capito che le variabili di ambiente definite dall'utente sarebbero state particolarmente utili come variabili di root globali, non sostituibili, utilizzabili nelle query multimediali. Ora, Dean "Dino" Jackson di Apple si unirà ad Atkins nel montaggio di livello 2.
Puoi iscriverti agli aggiornamenti su questo argomento nel w3c/csswg-drafts
numero # 1693 di GitHub . (Per dettagli storici particolarmente rilevanti, espandere i registri delle riunioni incorporati nelle risoluzioni del Bot di riunione CSSWG e cercare "MQ", che significa "query dei media".)
Ho intenzione di aggiornare questa domanda in futuro quando si verificano ulteriori sviluppi. Il futuro è eccitante.
Aggiornamento 2018-02-08 :
Safari Technology Preview 49 ha aggiunto il supporto per l'analisi calc()
nelle query multimediali, che può essere un preludio al supporto anche env()
in esse.
Aggiornamento 27-04-2018 : il team Chromium di Google ha deciso di iniziare a lavorare env()
. In risposta, Atkins ha iniziato a specificare env()
una bozza di standard separata e non ufficiale: il modulo 1 delle variabili di ambiente CSS . (Vedi il suo commento su GitHub in w3c / csswg-drafts # 1693 e il suo commento in w3c / csswg-drafts # 1817 ). La bozza richiama le variabili nelle query multimediali come un caso d'uso esplicito:
Poiché le variabili di ambiente non dipendono dal valore di qualsiasi cosa tratto da un particolare elemento, possono essere utilizzate in luoghi in cui non è presente alcun elemento evidente da cui attingere, ad esempio nelle
@media
regole, in cui lavar()
funzione non sarebbe valida.
Se leggi le specifiche e hai dei dubbi, o se desideri esprimere il tuo supporto per il caso d'uso di media query, puoi comunque farlo in GitHub w3c / csswg-drafts # 1693 o in qualsiasi problema CSS di GitHub con il prefisso "[ css-env-1] ” .
Aggiornamento 2019-07-06 : il lavoro continua sulle specifiche. Il numero # 2627 di GitHub e il numero # 3578 di GitHub sono dedicati alle variabili ambientali personalizzate nelle query multimediali.
Quello che PUOI fare, tuttavia, è @media query your: istruzione root!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
Funziona totalmente in Chrome, Firefox e Edge almeno le ultime versioni di produzione al momento della pubblicazione.
var
, quindi può essere utilizzato nei calcoli altrove nel css
, ciò richiede comunque di mettere il "valore magico" (qui, 479px) in due punti: la media query e una dichiarazione var.
Apparentemente non è possibile usare variabili CSS native come quella. È uno dei limiti .
Un modo intelligente di usarlo è quello di cambiare le variabili nella media-query, per influenzare tutto il tuo stile. Raccomando questo articolo .
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
Un modo per ottenere ciò che vuoi è usare il pacchetto npm postcss-media-variables
.
Se stai bene usando i pacchetti npm, puoi dare un'occhiata alla documentazione per lo stesso qui
Esempio
/* 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) {}
Come puoi leggere altre risposte, non è ancora possibile farlo.
Qualcuno ha menzionato le variabili ambientali personalizzate (simili alle variabili CSS personalizzate env()
anziché var()
) e il principio è valido, sebbene ci siano ancora 2 problemi principali:
È possibile utilizzare JavaScript per modificare il valore delle media query e impostarlo sul valore di una variabile 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 = '..'
Ho scritto una piccola sceneggiatura che puoi includere nella tua pagina. Sostituisce ogni regola multimediale con un valore di 1px
con il valore della variabile css --replace-media-1px
, regole con valore 2px
con --replace-media-2px
e così via. Questo funziona per le media query with
, min-width
, max-width
, height
, min-height
e max-height
anche quando sono collegati tramite 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) {
...
}