目前 Chrome 63+、Edge 16+、Firefox 57+、Safari 11+、iOS Safari 11.2+、Android 62+ 以及几乎所有的移动端浏览器都支持@support
属性(只有 IE 不支持,不过这并不重要).
我们都知道 css 具有功能降级的特性,对于不认识的属性都会丢弃而继续应用下一行样式,平时我们也都是这样书写,但是这样书写会导致 css 样式赘余,后继者很难维护,因此可以考虑使用特征查询@supports
使用
body {
display: flex;
}
@supports (display: grid) {
body {
display: grid;
grid-template-columns: [c-start] 10rem [c-1-end] auto [c-end];
grid-template-rows: [r-start] 60px [r-1-end] auto [r-end];
}
}
只有当浏览器支持grid
的时候才会使用@support
里的块,否则会被忽略.
还有支持@support not
查询:
body {
display: grid;
grid-template-columns: [c-start] 10rem [c-1-end] auto [c-end];
grid-template-rows: [r-start] 60px [r-1-end] auto [r-end];
}
@supports not (display: grid) {
body {
display: flex;
}
}
还可以使用and
,or
进行查询:
@supports (display: grid) and (display: flex) {
body {
display: flex;
display: grid;
}
}
@supports (height: 100vh) or (width: 100vw) {
body {
height: 100vh;
width: 100vw;
}
}
非常简单有效,可以尝试在新项目中优先使用,使高版本的浏览器用户获得更好的体验,又或者可以在老项目中使用新 css 特性进行优化是升级.
这里推荐两款非常有用的 chrome dev 扩展工具:
- feature-queries-manager,通过这个工具我们可以很方便的进行调试.
- css-feature-toggle-devtools-extension,切换是否支持 css 特性.
JS
JavaScript 有一个 API,测试它是否支持:
if (window.CSS && window.CSS.supports) {
// Apparently old Opera had a weird implementation, so you could also do:
// !!((window.CSS && window.CSS.supports) || window.supportsCSS || false)
}
要使用它,要么在一个 param 中将属性名传递给它,在另一个 param 中传递值:
const supportsGrid = CSS.supports('display', 'grid');
或者在一个镜像 CSS 语法的字符串中全部给出:
const supportsGrid = CSS.supports('(display: grid)');