我正在尝试在媒体查询中使用CSS变量,但它不起作用。
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
答案 0 :(得分:64)
来自spec,
可以使用
var()
函数代替值的任何部分 元素上的任何属性。var()
函数不能用作 属性名称,选择器或除属性值之外的任何其他内容。 (这样做通常会产生无效的语法,或者是一个值为 意义与变量无关。)
所以不,你不能在媒体查询中使用它。
这是有道理的。因为您可以设置--mobile-breakpoint
,例如到:root
,即<html>
元素,并从那里继承到其他元素。但是媒体查询不是一个元素,它不会从<html>
继承,所以它无法工作。
这不是CSS变量试图完成的。您可以使用CSS预处理器。
答案 1 :(得分:39)
目前为Oriol has answered,CSS Variables Level 1’s var()
cannot be used in media queries。但是,最近的一些发展将解决这个问题。 在几年内,CSS Environment Variables Module Level 1标准化并实施后,我们就可以在所有现代浏览器中的媒体查询中使用env()
变量。
如果您阅读specification并有疑虑,或者您想表达对媒体查询用例的支持,您仍然可以在GitHub w3c/csswg-drafts#1693或{{3}中执行此操作}。
原始答案 2017-11-09 :
最近,{strong> CSS变量等级2 any CSS GitHub issue prefixed with “[css-env-1]”将使用env()
支持用户定义的环境变量,并且他们会尝试使它们在媒体查询中有效。在2017年9月正式发布iPhone X之前不久,该集团解决了这个问题CSS Working Group decided(另见after Apple first proposed standard user-agent properties)。其他浏览器代表随后同意它们通常可用于许多设备,例如电视显示器和带有出血边缘的墨水打印。 (env()
过去曾被称为constant()
,但现已弃用。您可能仍会看到引用旧名称的文章,例如WebKit: “Designing Websites for iPhone X” by Timothy Horton。)几周后,{ {3}}这些环境变量可用于媒体查询,this article by Peter-Paul Koch用户定义的环境变量作为媒体查询中可用的全局,不可覆盖的根变量特别有用。现在,Cameron McCormack of Mozilla realized正在编辑第2级。
您可以在Tab Atkins, Jr. of Google then realized订阅有关此问题的更新。 (有关特别相关的历史详细信息,请展开嵌入在Dean “Dino” Jackson of Apple will join Atkins中的会议日志,并搜索“MQ”,它代表“媒体查询”。)
我计划在将来发生更多事态发展时更新这个问题。未来是令人兴奋的。
更新 2018-02-08 :
w3c/csswg-drafts
GitHub issue #1693已添加对在媒体查询中解析calc()
的支持,这也可能是在其中支持env()
的前奏。
更新 2018-04-27 :
Google的Chromium团队决定开始致力env()
。作为回应,Atkins已开始在单独的非官方草案标准中指定env()
: CSSWG Meeting Bot’s resolutions 。 (请参阅Safari Technology Preview 49和CSS Environment Variables Module Level 1。)草案将媒体查询中的变量称为明确的用例:
因为环境变量不依赖于从特定元素中提取的任何内容的值,所以它们可以在没有明显元素可以绘制的地方使用,例如在
@media
规则中,{ {1}}函数无效。
如果您阅读规范并有疑虑,或者您想表达对媒体查询用例的支持,您仍然可以在his GitHub comment in w3c/csswg-drafts#1693或his comment in w3c/csswg-drafts#1817中执行此操作。
答案 2 :(得分:5)
实现目标的一种方法是使用npm包postcss-media-variables
。
如果您使用npm包很好,那么您可以在这里看一下documentatoin
实施例
/* 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) {}
答案 3 :(得分:4)
但是,您可以做的是@media查询您的:root语句!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
到目前为止,该版本至少可以在Chrome,Firefox和Edge上正常使用。
答案 4 :(得分:3)
显然,不可能使用像这样的原生CSS变量。这是limitations之一。
使用它的一种聪明方法是更改媒体查询中的变量,以影响您的所有风格。我推荐this article。
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
答案 5 :(得分:2)
您可以使用JavaScript更改媒体查询的值并将其设置为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 = '..'
我写了一个小脚本,您可以将其包含在页面中。它使用css变量1px
的值替换值为--replace-media-1px
的每个媒体规则,将值2px
替换为--replace-media-2px
的规则,依此类推。这适用于媒体查询with
,min-width
,max-width
,height
,min-height
和max-height
,即使它们使用{{1 }}。
JavaScript:
and
CSS:
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);
}
}
答案 6 :(得分:1)
您可以阅读其他答案,但仍然不可能。
有人提到自定义环境变量(类似于自定义css变量 env()
而不是var()
),尽管有两个主要问题,但原理是合理的:< / p>