Variabili native CSS che non funzionano nelle query multimediali


140

Sto cercando di utilizzare le variabili CSS nella media query e non funziona.

:root {
  --mobile-breakpoint: 642px;
}

@media (max-width: var(--mobile-breakpoint)) {

}

Hai provato con diversi browser? (Come Chrome e Firefox)
Cohars

1
Senza preprocessore @SandrinaPereira
Cohars

1
@SandrinaPereira Quindi puoi farlo su Firefox e Chrome 👍
Cohars,


3
Giusto per chiarire le persone che lo trovano tramite Google: è possibile utilizzare le proprietà personalizzate CSS nell'ambito di una query multimediale, non è possibile utilizzarle in una dichiarazione di query multimediale.
David Deprost,

Risposte:


112

Dalle specifiche ,

La var()funzione può essere utilizzata al posto di qualsiasi parte di un valore in qualsiasi proprietà di un elemento. La var()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-breakpointad 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.


77
La risposta è corretta in quanto la specifica non gestisce attualmente le variabili CSS nelle query multimediali, ma errata in ciò non è ciò che le variabili CSS stanno cercando di realizzare. Ridurre la ripetizione e i numeri magici è esattamente il motivo per cui sono state create le variabili CSS - vedi w3.org/TR/css-variables-1/#intro
mikemaccana,

69

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-draftsnumero # 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 @mediaregole, in cui la var()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.


31

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.


Wow grazie! Questa dovrebbe sicuramente essere la risposta corretta.
SimplyComplexable,

1
Buono a sapersi. Una limitazione: se è necessario accedere anche a quel valore come a 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.
ToolmakerSteve

8

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;
  }
}

Non capisco il significato di "cambia le tue variabili nella media-query", puoi mostrare un esempio?

1
Non intendevo questo. Ho chiesto informazioni sul valore della query multimediale.

4
Sì, ho appena fatto, è nell'articolo che ho collegato. So che non è quello che ti aspettavi, ma le variabili CSS non possono essere utilizzate per definire le query multimediali
Cohars,

8

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) {}

4
Grazie, ma stavo cercando di non usare alcun preprocessore.

et. al: Con postcss puoi anche usare cssnext cssnext.io/features/#custom-media-queries
sebilasse

1
@sebilasse: custom-media-query non risolve il problema principale di non poter utilizzare le variabili CSS come punti di interruzione per le query multimediali
zhirzh,

1
postcss non è un preprocessore

1

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:

  • supporto browser debole
  • finora non c'è modo di definirli (ma probabilmente lo sarà in futuro, dato che finora è solo una bozza non ufficiale)

1

Risposta breve

È 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 = '..'


Risposta lunga

Ho scritto una piccola sceneggiatura che puoi includere nella tua pagina. Sostituisce ogni regola multimediale con un valore di 1pxcon il valore della variabile css --replace-media-1px, regole con valore 2pxcon --replace-media-2pxe così via. Questo funziona per le media query with, min-width, max-width, height, min-heighte max-heightanche 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) {
  ...
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.