Ich versuche, CSS-Variablen in Medienabfragen zu verwenden, und es funktioniert nicht.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Ich versuche, CSS-Variablen in Medienabfragen zu verwenden, und es funktioniert nicht.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Antworten:
Aus der Spezifikation ,
Die
var()
Funktion kann anstelle eines beliebigen Teils eines Werts in einer beliebigen Eigenschaft eines Elements verwendet werden. Dievar()
Funktion kann nicht als Eigenschaftsnamen, Selektoren oder andere Elemente als Eigenschaftswerte verwendet werden. (Dies führt normalerweise zu einer ungültigen Syntax oder zu einem Wert, dessen Bedeutung keine Verbindung zur Variablen hat.)
Nein, Sie können es nicht in einer Medienabfrage verwenden.
Und das macht Sinn. Denn Sie können --mobile-breakpoint
zB auf :root
das <html>
Element setzen und von dort an andere Elemente vererbt werden. Eine Medienabfrage ist jedoch kein Element, von dem sie nicht erbt <html>
, sodass sie nicht funktionieren kann.
Dies ist nicht das, was CSS-Variablen erreichen wollen. Sie können stattdessen einen CSS-Präprozessor verwenden.
Wie Oriol geantwortet hat, können CSS-Variablen der Stufe 1 var()
derzeit nicht in Medienabfragen verwendet werden . Es gab jedoch jüngste Entwicklungen, die dieses Problem angehen werden. In einigen Jahren, sobald das CSS-Umgebungsvariablenmodul Level 1 standardisiert und implementiert ist, können wir env()
Variablen in Medienabfragen in allen modernen Browsern verwenden.
Wenn Sie die Spezifikation lesen und Bedenken haben oder Ihre Unterstützung für den Anwendungsfall für Medienabfragen zum Ausdruck bringen möchten , können Sie dies dennoch in GitHub w3c / csswg-Drafts # 1693 oder in einem CSS-GitHub-Problem mit dem Präfix „[ css-env-1] ” .
Ursprüngliche Antwort 09.11.2017 : Vor kurzem hat die CSS-Arbeitsgruppe entschieden, dass CSS-Variablen der Stufe 2 benutzerdefinierte Umgebungsvariablen verwenden env()
und versuchen, sie in Medienabfragen gültig zu machen . Die Gruppe löste dies, nachdem Apple kurz vor der offiziellen Ankündigung des iPhone X im September 2017 erstmals Standard-Eigenschaften für Benutzeragenten vorgeschlagen hatte (siehe auch WebKit: „Entwerfen von Websites für das iPhone X“ von Timothy Horton ). Andere Browser-Vertreter waren sich dann einig, dass sie für viele Geräte wie Fernsehbildschirme und Tintendruck mit Beschnittungskanten im Allgemeinen nützlich sind. (wurde env()
früher genanntconstant()
, aber das ist jetzt veraltet. Möglicherweise sehen Sie immer noch Artikel, die sich auf den alten Namen beziehen, wie z. B. diesen Artikel von Peter-Paul Koch .) Nach einigen Wochen erkannte Cameron McCormack von Mozilla, dass diese Umgebungsvariablen in Medienabfragen verwendet werden können, und Tab Atkins, Jr. von Google erkannte dann, dass benutzerdefinierte Umgebungsvariablen besonders nützlich sind als globale, nicht überschreibbare Stammvariablen, die in Medienabfragen verwendet werden können. Jetzt wird Dean "Dino" Jackson von Apple zusammen mit Atkins Level 2 bearbeiten.
Sie können Updates zu diesem Thema in der w3c/csswg-drafts
GitHub-Ausgabe Nr. 1693 abonnieren . (Erweitern Sie für besonders relevante historische Details die in den Auflösungen des CSSWG Meeting Bot eingebetteten Besprechungsprotokolle und suchen Sie nach "MQ", was für "Medienabfragen" steht.)
Ich plane, diese Frage in Zukunft zu aktualisieren, wenn weitere Entwicklungen auftreten. Die Zukunft ist aufregend.
Update 2018-02-08 :
Safari Technology Preview 49 hat Unterstützung für das Parsen calc()
in Medienabfragen hinzugefügt , was möglicherweise auch ein Auftakt für die Unterstützung env()
in diesen ist.
Update 27.04.2018 : Das Chromium-Team von Google hat beschlossen, mit der Arbeit zu beginnen env()
. Als Reaktion darauf hat Atkins begonnen, env()
in einem separaten, inoffiziellen Standardentwurf festzulegen : das CSS-Umgebungsvariablenmodul Level 1 . (Siehe seinen GitHub-Kommentar in w3c / csswg-Drafts # 1693 und seinen Kommentar in w3c / csswg-Drafts # 1817. ) Der Entwurf ruft Variablen in Medienabfragen als expliziten Anwendungsfall auf:
Da Umgebungsvariablen nicht vom Wert eines aus einem bestimmten Element gezeichneten Elements abhängen, können sie an Stellen verwendet werden, an denen kein offensichtliches Element zum Zeichnen vorhanden ist, z. B. in
@media
Regeln, in denen dievar()
Funktion nicht gültig wäre.
Wenn Sie die Spezifikation lesen und Bedenken haben oder Ihre Unterstützung für den Anwendungsfall für Medienabfragen zum Ausdruck bringen möchten , können Sie dies dennoch in GitHub w3c / csswg-Drafts # 1693 oder in einem CSS-GitHub-Problem mit dem Präfix „[ css-env-1] ” .
Update 2019-07-06 : Die Arbeiten an den Spezifikationen werden fortgesetzt. GitHub-Ausgabe Nr. 2627 und GitHub-Ausgabe Nr. 3578 sind benutzerdefinierten Umgebungsvariablen in Medienabfragen gewidmet.
Was Sie jedoch tun können, ist @media, fragen Sie Ihre: root-Anweisung ab!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
Funktioniert vollständig in Chrome, Firefox und Edge, mindestens den neuesten Produktionsversionen ab diesem Beitrag.
var
um ihn in anderen Berechnungen verwenden zu können css
, müssen Sie den "magischen Wert" (hier 479px) an zwei Stellen eingeben: der Medienabfrage und einer var-Deklaration.
Anscheinend ist es einfach nicht möglich, solche nativen CSS-Variablen zu verwenden. Das ist eine der Einschränkungen .
Eine clevere Möglichkeit, es zu verwenden, besteht darin, Ihre Variablen in der Medienabfrage zu ändern, um Ihren gesamten Stil zu beeinflussen. Ich empfehle diesen Artikel .
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
Eine Möglichkeit, das zu erreichen, was Sie wollen, ist die Verwendung des npm-Pakets postcss-media-variables
.
Wenn Sie mit der Verwendung von npm-Paketen einverstanden sind, können Sie hier eine Dokumentation finden
Beispiel
/* 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) {}
Da Sie andere Antworten lesen können, ist dies immer noch nicht möglich .
Jemand erwähnte benutzerdefinierte Umgebungsvariablen (ähnlich wie benutzerdefinierte CSS-Variablen env()
anstelle von var()
), und das Prinzip ist solide, obwohl es immer noch zwei Hauptprobleme gibt:
Sie können JavaScript verwenden, um den Wert von Medienabfragen zu ändern und auf den Wert einer CSS-Variablen festzulegen.
// 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 = '..'
Ich habe ein kleines Skript geschrieben, das Sie auf Ihrer Seite einfügen können. Es ersetzt jede Medienregel durch einen Wert von 1px
durch den Wert der CSS-Variablen --replace-media-1px
, Regeln durch einen Wert 2px
mit --replace-media-2px
und so weiter. Dies funktioniert für die Medien - Anfragen with
, min-width
, max-width
, height
, min-height
und max-height
auch wenn sie mit verbunden sind 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) {
...
}