我试图在媒体查询中使用CSS变量,但它不起作用。

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

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

}

当前回答

显然,像这样使用原生CSS变量是不可能的。这是局限性之一。

使用它的一个聪明的方法是改变media-query中的变量,以影响你的所有风格。我推荐这篇文章。

:root {
  --gutter: 4px;
}

section {
  margin: var(--gutter);
}

@media (min-width: 600px) {
  :root {
    --gutter: 16px;
  }
}

其他回答

正如Oriol所回答的,CSS变量级别1的var()目前不能在媒体查询中使用。然而,最近的事态发展将解决这一问题。一旦CSS环境变量模块第1级标准化并实现,我们将能够在所有现代浏览器的媒体查询中使用env()变量。

CSS工作组(CSSWG)在一个新标准中编纂了env()(目前处于草案阶段):CSS环境变量模块第1级(参见这条GitHub评论和这条评论了解更多信息)。草案将媒体查询中的变量作为一个显式用例:

因为环境变量不依赖于从特定元素中抽取的任何值,所以它们可以用于没有明显元素可抽取的地方,例如在@media规则中,其中var()函数是无效的。

如果你阅读了规范并有一个问题,或者如果你想表达你对媒体查询用例的支持,你可以在第2627期,第3578期,或任何标记为“CSS -env-1”的CSS GitHub问题中这样做。

GitHub issue #2627和GitHub issue #3578致力于媒体查询中的自定义环境变量。


Original answer from 2017-11-09: Recently, the CSS Working Group decided that CSS Variables Level 2 will support user-defined environment variables using env(), and they will try to make them be valid in media queries. The Group resolved this after Apple first proposed standard user-agent properties, shortly before the official announcement of iPhone X in September 2017 (see also WebKit: “Designing Websites for iPhone X” by Timothy Horton). Other browser representatives then agreed they would be generally useful across many devices, such as television displays and ink printing with bleed edges. (env() used to be called constant(), but that has now been deprecated. You might still see articles that refer to the old name, such as this article by Peter-Paul Koch.) After some weeks passed, Cameron McCormack of Mozilla realized that these environment variables would be usable in media queries, and Tab Atkins, Jr. of Google then realized that user-defined environment variables would be especially useful as global, non-overridable root variables usable in media queries. Now, Dean “Dino” Jackson of Apple will join Atkins in editing Level 2.

您可以在w3c/ CSSWG -drafts GitHub issue #1693中订阅有关此问题的更新(特别是相关的历史细节,扩展嵌入CSSWG会议机器人决议中的会议日志,并搜索“MQ”,即“媒体查询”)。

正如你可以阅读其他答案,仍然不可能这样做。

有人提到了自定义环境变量(类似于自定义css变量env()而不是var()),原理是合理的,尽管仍然有2个主要问题:

浏览器支持弱 到目前为止,还没有办法定义它们(但可能在未来会,因为到目前为止这只是一个非官方的草案)

显然,像这样使用原生CSS变量是不可能的。这是局限性之一。

使用它的一个聪明的方法是改变media-query中的变量,以影响你的所有风格。我推荐这篇文章。

:root {
  --gutter: 4px;
}

section {
  margin: var(--gutter);
}

@media (min-width: 600px) {
  :root {
    --gutter: 16px;
  }
}

你可以使用matchMedia以编程方式构建一个媒体查询:

const mobile_breakpoint = "642px";
const media_query = window.matchMedia(`(max-width: ${mobile_breakpoint})`);
function toggle_mobile (e) {
  if (e.matches) {
    document.body.classList.add("mobile");
  } else {
    document.body.classList.remove("mobile");
  }
}
// call the function immediately to set the initial value:
toggle_mobile(media_query);
// watch for changes to update the value:
media_query.addEventListener("change", toggle_mobile);

然后,不是在CSS文件中使用媒体查询,而是在body有mobile类时应用所需的规则:

.my-div {
  /* large screen rules */
}

.mobile .my-div {
  /* mobile screen rules */
}

实现你想要的一个方法是使用npm包postcss-media-variables。

如果你可以使用npm包,那么你可以在这里查看相同的文档:

postcss-media-variables

例子

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