如何使用 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.supports
和CSS
global 是同时引入的,所以也不需要检查。)
创建browserCanUseCssVariables()
函数
在您的情况下,我们可以通过简单地执行相同的逻辑来创建 browserCanUseCssVariables()
函数。下面这个 sn-p 将根据支持提醒true
或false
。
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 转换?