95 css media-queries css-variables
我试图在媒体查询中使用CSS变量,但它不起作用.
:root {
--mobile-breakpoint: 642px;
}
@media (max-width: var(--mobile-breakpoint)) {
}
Run Code Online (Sandbox Code Playgroud)
Ori*_*iol 81
从规格来看,
该
var()函数可用于代替元素上任何属性中值的任何部分.该var()函数不能用作属性名称,选择器或属性值之外的任何其他内容.(这样做通常会产生无效的语法,或者其含义与变量无关的值.)
所以不,你不能在媒体查询中使用它.
这是有道理的.因为你可以设置--mobile-breakpointeg :root,即<html>元素,并从那里继承到其他元素.但是媒体查询不是一个元素,它不会继承<html>,所以它无法工作.
这不是CSS变量试图完成的.您可以使用CSS预处理器.
jsc*_*hoi 53
正如Oriol已经回答的那样,目前,CSS Variables Level 1 var()不能用于媒体查询.但是,最近的一些发展将解决这个问题.几年后,一旦CSS环境变量模块1级标准化并实现,我们就可以env()在所有现代浏览器中使用媒体查询中的变量.
如果您阅读规范并有疑虑,或者您想表达对媒体查询用例的支持,您仍然可以在GitHub w3c/csswg-drafts#1693或任何带有"[前缀"的CSS GitHub问题中执行此操作. css-env-1]".
原来的答复2017年11月9日:近日,CSS工作组决定是CSS变量2级将使用支持用户自定义的环境变量env(),他们会尽量让他们在媒体查询有效.在2017年9月iPhone X官方发布之前不久,该集团在Apple首次提出标准用户代理属性后解决了这一问题(另请参阅WebKit:Timothy Horton为"设计iPhone X网站").其他浏览器代表随后同意它们通常可用于许多设备,例如电视显示器和带有出血边缘的墨水打印.(env()曾经被称为constant(),但现在已被弃用.你可能仍会看到引用旧名称的文章,例如Peter-Paul Koch撰写的这篇文章.)几周后,Mozilla的Cameron McCormack意识到这些环境变量可以在媒体查询中使用,然后Google的Tab Atkins,Jr.意识到用户定义的环境变量作为媒体查询中可用的全局,不可覆盖的根变量特别有用.现在,Apple的Dean"Dino"Jackson将加入Atkins编辑Level 2.
您可以在w3c/csswg-draftsGitHub问题#1693中订阅有关此问题的更新.(有关特别相关的历史详细信息,请展开CSSWG Meeting Bot解决方案中嵌入的会议日志,并搜索"MQ",它代表"媒体查询".)
我计划在将来发生更多事态发展时更新这个问题.未来是令人兴奋的.
更新2018-02-08:
Safari Technology Preview 49增加了calc()对媒体查询中解析的支持,这也可能是支持env()它们的前奏.
更新2018-04-27:Google的Chromium团队已决定开始工作env().作为回应,Atkins已开始env()在单独的非官方草案标准中指定:CSS环境变量模块1级.(参见他在W3c/csswg-drafts#1693中的GitHub评论和他在w3c/csswg-drafts#1817中的评论.)草案将媒体查询中的变量称为明确的用例:
因为环境变量不依赖于从特定元素中提取的任何内容的值,所以它们可以在没有明显元素可以绘制的地方使用,例如在
@media规则中,var()函数无效.
如果您阅读规范并有疑虑,或者您想表达对媒体查询用例的支持,您仍然可以在GitHub w3c/csswg-drafts#1693或任何带有"[前缀"的CSS GitHub问题中执行此操作. css-env-1]".
Tem*_*fif 24
媒体查询的第 5 级规范定义了几乎可以完成您正在寻找的任务的自定义媒体查询。它允许您像处理 CSS 变量一样定义断点,然后在不同的地方使用它们。
规范中的示例:
@custom-media --narrow-window (max-width: 30em);
@media (--narrow-window) {
/* narrow window styles */
}
@media (--narrow-window) and (script) {
/* special styles for when script is allowed */
}
Run Code Online (Sandbox Code Playgroud)
实际上仍然不支持此功能,因此我们必须等待才能使用此功能。
小智 13
但是,您可以做的是@media查询您的:root语句!
:root {
/* desktop vars */
}
@media screen and (max-width: 479px) {
:root {
/* mobile vars */
}
}
Run Code Online (Sandbox Code Playgroud)
截至本文发布时,至少可以在Chrome,Firefox和Edge上完全运行。
实现您想要的一种方法是使用npm package postcss-media-variables。
如果您可以使用npm软件包,则可以在此处查看文档
例
/* 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) {}
Run Code Online (Sandbox Code Playgroud)
显然,不可能像这样使用本机CSS变量。这是局限性之一。
一种聪明的使用方法是更改媒体查询中的变量,以影响所有样式。我推荐这篇文章。
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
您可以使用 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 = '..'
Run Code Online (Sandbox Code Playgroud)
我写了一个小脚本,您可以将其包含在您的页面中。它将每个媒体规则的值替换1px为 css 变量的值--replace-media-1px,规则的值2px替换为 with--replace-media-2px等等。该方法适用于媒体查询with,min-width,max-width,height,min-height和max-height即使他们使用连接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);
}
}
Run Code Online (Sandbox Code Playgroud)
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) {
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27300 次 |
| 最近记录: |