J'essaie d'utiliser des variables CSS dans la requête multimédia et cela ne fonctionne pas.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
J'essaie d'utiliser des variables CSS dans la requête multimédia et cela ne fonctionne pas.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Réponses:
De la spécification ,
La
var()
fonction peut être utilisée à la place de n'importe quelle partie d'une valeur dans n'importe quelle propriété d'un élément. Lavar()
fonction ne peut pas être utilisée comme noms de propriété, sélecteurs ou autre chose que les valeurs de propriété. (Cela produit généralement une syntaxe invalide, ou bien une valeur dont la signification n'a aucun lien avec la variable.)
Donc non, vous ne pouvez pas l'utiliser dans une requête multimédia.
Et cela a du sens. Parce que vous pouvez définir --mobile-breakpoint
par exemple à :root
, c'est-à-dire l' <html>
élément, et de là être hérité à d'autres éléments. Mais une requête multimédia n'est pas un élément, elle n'hérite pas <html>
, donc elle ne peut pas fonctionner.
Ce n'est pas ce que les variables CSS essaient d'accomplir. Vous pouvez utiliser un préprocesseur CSS à la place.
Comme Oriol a répondu , actuellement, les variables CSS de niveau 1 ne var()
peuvent pas être utilisées dans les requêtes multimédias . Cependant, des développements récents permettront de résoudre ce problème. Dans quelques années, une fois que le module de variables d'environnement CSS niveau 1 sera standardisé et implémenté, nous pourrons utiliser des env()
variables dans les requêtes multimédias dans tous les navigateurs modernes.
Si vous lisez la spécification et avez un problème, ou si vous souhaitez exprimer votre soutien pour le cas d'utilisation de la requête multimédia, vous pouvez toujours le faire dans GitHub w3c / csswg-drafts # 1693 ou dans tout problème CSS GitHub préfixé par "[ css-env-1] » .
Réponse originale 09/11/2017 : Récemment, le groupe de travail CSS a décidé que les variables CSS de niveau 2 prendront en charge les variables d'environnement définies par l'utilisateur env()
et essaieront de les rendre valides dans les requêtes multimédias . Le Groupe a résolu ce problème après qu'Apple ait proposé pour la première fois des propriétés d'agent utilisateur standard , peu de temps avant l'annonce officielle de l'iPhone X en septembre 2017 (voir également WebKit: «Conception de sites Web pour iPhone X» par Timothy Horton ). D'autres représentants de navigateurs ont alors convenu qu'ils seraient généralement utiles sur de nombreux appareils, tels que les écrans de télévision et l'impression à l'encre avec des bords perdus. ( env()
anciennement appeléconstant()
, mais cela est désormais obsolète. Vous verrez peut-être encore des articles faisant référence à l'ancien nom, comme cet article de Peter-Paul Koch .) Après quelques semaines, Cameron McCormack de Mozilla s'est rendu compte que ces variables d'environnement seraient utilisables dans les requêtes médiatiques, et Tab Atkins, Jr. de Google s'est alors rendu compte que les variables d'environnement définies par l'utilisateur seraient particulièrement utiles en tant que variables racine globales et non remplaçables utilisables dans les requêtes multimédias. Désormais, Dean «Dino» Jackson d'Apple se joindra à Atkins pour éditer le niveau 2.
Vous pouvez vous abonner aux mises à jour sur ce sujet dans le w3c/csswg-drafts
numéro 1693 de GitHub . (Pour des détails historiques particulièrement pertinents, développez les journaux de réunion intégrés dans les résolutions du CSSWG Meeting Bot et recherchez «MQ», qui signifie «requêtes médias».)
Je prévois de mettre à jour cette question à l'avenir lorsque d'autres développements se produiront. L'avenir est passionnant.
Mise à jour 2018-02-08 :
Safari Technology Preview 49 a ajouté la prise en charge de l'analyse calc()
dans les requêtes multimédias, ce qui peut être un prélude à env()
leur prise en charge.
Mise à jour 27/04/2018 : l'équipe Chromium de Google a décidé de commencer à travailler env()
. En réponse, Atkins a commencé à spécifier env()
dans un projet de norme séparé et non officiel: le module de variables d'environnement CSS niveau 1 . (Voir son commentaire GitHub dans w3c / csswg-drafts # 1693 et son commentaire dans w3c / csswg-drafts # 1817. ) Le brouillon appelle les variables dans les requêtes multimédias comme cas d'utilisation explicite:
Étant donné que les variables d'environnement ne dépendent pas de la valeur de tout élément tiré d'un élément particulier, elles peuvent être utilisées dans des endroits où il n'y a pas d'élément évident à partir
@media
duquel tirer, comme dans les règles, où lavar()
fonction ne serait pas valide.
Si vous lisez la spécification et avez un problème, ou si vous souhaitez exprimer votre soutien pour le cas d'utilisation de la requête multimédia, vous pouvez toujours le faire dans GitHub w3c / csswg-drafts # 1693 ou dans tout problème CSS GitHub préfixé par "[ css-env-1] » .
Mise à jour 2019-07-06 : Le travail se poursuit sur les spécifications. Le numéro 2627 de GitHub et le numéro 3578 de GitHub sont consacrés aux variables d'environnement personnalisées dans les requêtes multimédias.
Ce que vous POUVEZ faire cependant, c'est @media interroger votre instruction: root!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
Fonctionne totalement dans Chrome, Firefox et Edge au moins les dernières versions de production à partir de cette publication.
var
, afin de pouvoir l'utiliser dans des calculs ailleurs dans le css
, cela nécessite toujours de mettre la "valeur magique" (ici, 479px) à deux endroits: la requête multimédia et une déclaration var.
Apparemment, il n'est tout simplement pas possible d'utiliser des variables CSS natives comme ça. C'est l'une des limites .
Une manière intelligente de l'utiliser est de changer vos variables dans la requête média, pour avoir un impact sur tout votre style. Je recommande cet article .
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
Une façon d'obtenir ce que vous voulez est d'utiliser le package npm postcss-media-variables
.
Si vous êtes d'accord avec l'utilisation des packages npm, vous pouvez consulter la documentation pour la même chose ici
Exemple
/* 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) {}
Comme vous pouvez lire d'autres réponses, il n'est toujours pas possible de le faire.
Quelqu'un a mentionné des variables d'environnement personnalisées (similaires aux variables css personnalisées env()
au lieu de var()
), et le principe est valable, bien qu'il y ait encore 2 problèmes majeurs:
Vous pouvez utiliser JavaScript pour modifier la valeur des requêtes multimédias et la définir sur la valeur d'une variable 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 = '..'
J'ai écrit un petit script que vous pouvez inclure sur votre page. Il remplace chaque règle de média par une valeur de 1px
par la valeur de la variable css --replace-media-1px
, les règles par une valeur 2px
par --replace-media-2px
et ainsi de suite. Cela fonctionne pour les requêtes des médias with
, min-width
, max-width
, height
, min-height
et max-height
même quand ils sont connectés à l' aide 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) {
...
}