如何使用 JavaScript 检测 CSS 变量支持?

Posted

技术标签:

【中文标题】如何使用 JavaScript 检测 CSS 变量支持?【英文标题】:How can I detect CSS Variable support with JavaScript? 【发布时间】:2014-12-25 07:53:44 【问题描述】:

最新版本的 Firefox 支持CSS Variables,但 Chrome、IE 和许多其他浏览器不支持。应该可以访问 DOM 节点或编写一个返回浏览器是否支持此功能的小方法,但我无法找到当前能够执行此操作的任何内容。我需要的是一个解决方案,如果浏览器不支持该功能,我可以将其用作运行代码的条件,例如:

if (!browserCanUseCssVariables()) 
  // Do stuff...

【问题讨论】:

我找不到此功能的任何功能检测。就个人而言,我建议不要打扰它。目前还没有计划在 chrome 中实现这一点,更不用说 IE... 这里是支持的浏览器列表:caniuse.com/#feat=css-variables 完全正确,但我正在开发一个 javascript 版本,它应该取代这种行为——当然,只有在浏览器不能运行的情况下,它才会发挥它的魔力。 github.com/IceReaper/NextCSS 请注意,Firefox 不支持通过 CSSOM 访问 CSS 变量,尽管它目前支持在 CSS 中声明和使用它们。但是,如果您只是对事物的 CSS 方面进行功能检测而不尝试访问值本身,那么这应该不是什么大问题。 这种情况不再存在,请查看this。 IE 是唯一不支持 CSS 变量的主流浏览器。 【参考方案1】:

我们可以通过CSS.supports 做到这一点。这是 CSS 的 @supports 规则的 JavaScript 实现,目前可在 Firefox、Chrome、Opera 和 android 浏览器中使用(参见 Can I Use...)。

CSS.supports() 静态方法返回一个布尔值,指示浏览器是否支持给定的 CSS 功能。– Mozilla Developer Network

有了这个,我们可以简单地:

CSS.supports('color', 'var(--fake-var)');

如果浏览器支持 CSS 变量,结果将是 true,如果不支持,结果将是 false

(您可能认为 CSS.supports('--fake-var', 0) 会起作用,但正如 cmets 在此答案中所指出的那样,Safari 似乎有一个错误使其失败。)

纯 JavaScript 示例

在 Firefox 上,此代码 sn-p 将产生绿色背景,因为我们上面的 CSS.supports 调用返回 true。在不支持 CSS 变量的浏览器中,背景将为红色。

var body = document.getElementsByTagName('body')[0];

if (window.CSS && CSS.supports('color', 'var(--fake-var)')) 
  body.style.background = 'green';
 else 
  body.style.background = 'red';

请注意,这里我还添加了检查 window.CSS 是否存在 - 这将防止在不支持此 JavaScript 实现的浏览器中引发错误,并将其视为 false。 (CSS.supportsCSS global 是同时引入的,所以也不需要检查。)

创建browserCanUseCssVariables() 函数

在您的情况下,我们可以通过简单地执行相同的逻辑来创建 browserCanUseCssVariables() 函数。下面这个 sn-p 将根据支持提醒truefalse

function browserCanUseCssVariables() 
  return window.CSS && CSS.supports('color', 'var(--fake-var)');


if (browserCanUseCssVariables()) 
    alert('Your browser supports CSS Variables!');
 else 
    alert('Your browser does not support CSS Variables and/or CSS.supports. :-(');

结果(全部仅在 Windows 上测试)

火狐v31

Chrome v38

Internet Explorer 11

【讨论】:

在启用 CSS 实验性功能时不适用于 Chrome。不管它总是返回false 在 Chrome 60 稳定版中工作 - 在控制台中输入:“window.CSS && window.CSS.supports && window.CSS.supports('--fake-var', 0)”,返回 true @ChrisMorgan 当我在 Safari 12.0.2 上尝试 window.CSS.supports('--fake-var', 0) 时,它返回 false 但实际上支持 CSS 变量。然而,这返回 true(取自 Modernizr):window.CSS.supports('color', 'var(--primary)') 感谢您的澄清,很高兴知道。所以 应该 等效的两个实际上不在 Safari 中(可能是一个错误),因此检查 var(--x) value 应该优于 --x 财产。我已经更新了解决该错误的答案。 Mozilla 文档使用CSS.supports('(--foo: red)'),这似乎更直接。不过写得很好。【参考方案2】:

使用 CSS 变量设置 CSS 样式,并使用 Javascript 和 getComputedStyle() 进行验证(如果已设置)... 很多浏览器都支持getComputedStyle():http://caniuse.com/#feat=getcomputedstyle

HTML

<div class="css-variable-test"></div>

CSS

:root 
  --main-bg-color: rgb(1, 2, 3); /* or something else */


.css-variable-test 
    display: none;
    background-color: var(--main-bg-color);

JavaScript

var computedStyle = getComputedStyle(document.getElementsByClassName('css-variable-test')[0], null);

if (computedStyle.backgroundColor == "rgb(1, 2, 3)")  // or something else
    alert('CSS variables support');

小提琴:http://jsfiddle.net/g0naedLh/6/

【讨论】:

如果您有权修改 CSS,那么这个解决方案可能比我的更好,纯粹是因为目前并非所有浏览器都支持 JavaScript 的 CSS.supports 实现,我的回答依赖于此。所以 +1 ! @JamesDonnelly Thx,实际上您的解决方案是绝对正确的,因为只有 firefox 支持这一点并且还支持 CSS.supports... 不错的解决方案。【参考方案3】:

您不需要 Javascript 来检测浏览器是否支持自定义属性,除非 Do stuff... 本身就是 Javascript。由于您检测到的支持是 CSS,我假设您尝试做的事情都是 CSS。因此,如果有办法从这个特定问题中删除 JS,我会推荐Feature Queries。

@supports (display: var(--prop)) 
  h1  font-weight: normal; 
  /* all the css, even without var() */

功能查询测试对语法的支持。您不必查询display;你可以使用任何你想要的属性。同样,--prop 的值甚至不需要存在。您所做的只是检查浏览器是否知道如何读取该语法。

(我只是选择了display,因为几乎每个浏览器都支持它。如果您使用flex-wrap 或其他东西,您将无法捕捉到支持自定义道具但不支持flexbox的浏览器。)

旁注:我更喜欢称它们为 自定义属性,因为它们就是这样:作者定义的属性。是的,您可以将它们使用作为变量,但它们作为属性有一定的优势,例如 DOM 继承:

body     --color-heading: green; 
article  --color-heading: blue; 
h1       color: var(--color-heading);  /* no need for descendant selectors */

【讨论】:

为什么你不必使用 JS 检测,问题是针对 javascript 的,并且应该假设在某些情况下这种检测是绝对必须在 JS 中进行的,而不是在 CSS 中。例如,如果不支持脚本的使用,您希望阻止脚本运行甚至被导入。【参考方案4】:

我在让 window.CSS.supports 方法在 chrome 49 中测试 css 变量时遇到问题(即使它具有本机支持)。最终这样做了:

var supportsCssVars = function() 
    var s = document.createElement('style'),
        support;

    s.innerhtml = ":root  --tmp-var: bold; ";
    document.head.appendChild(s);
    support = !!(window.CSS && window.CSS.supports && window.CSS.supports('font-weight', 'var(--tmp-var)'));
    s.parentNode.removeChild(s);
    return support;


console.log("Supports css variables:", supportsCssVars());

似乎可以在我测试过的所有浏览器中使用。 不过可能代码可以优化。

【讨论】:

以上是关于如何使用 JavaScript 检测 CSS 变量支持?的主要内容,如果未能解决你的问题,请参考以下文章

你如何检测 CSS 动画何时以 JavaScript 开始和结束?

使用 Javascript(并且没有modernizr)检测 CSS 转换?

如何将scss变量设置为css变量使用javascript

如何使用 JavaScript 在 NativeScript 中读取 CSS 变量

如何使用 CSS 媒体查询检测设备方向?

Javascript检测屏幕分辨率,更改css,相应裁剪图像