@supports 用于检测CSS特性是否被浏览器原生支持,仅在支持时应用样式;它不触发重排、不依赖UA,但无法检测实现完整性或运行时行为。

怎么用 @supports 检测 CSS 特性是否可用
直接用 @supports 规则包裹样式块,浏览器会先检查括号内的声明是否被原生支持,只在支持时才应用内部样式。它不是 JavaScript 判断,不触发重排,也不依赖 UA 或屏幕尺寸。
常见错误是写成 @supports (display: grid) 却期望它兼容 IE —— 实际上 IE 完全不识别 @supports,整条规则会被忽略(这是正确行为,不是 bug)。
-
@supports必须写在顶层或@media内部,不能嵌套在选择器里 - 括号内必须是完整的声明(
property: value),不能只写属性名,比如@supports (display)无效 - 支持逻辑运算符:
and、or、not,但注意not (display: grid)外层要加括号 - 值必须是浏览器实际能解析的合法语法,例如
@supports (font-variation-settings: normal)中normal是有效值,而@supports (font-variation-settings: "wght 400")会失败(引号内不是标准值)
@supports 和 Modernizr 什么情况下该选谁
@supports 足够应对大多数现代 CSS 特性检测,比如 gap、aspect-ratio、container-query。它轻量、无 JS 依赖、可被 CSS 预处理器处理。
Modernizr 仍有不可替代的场景:需要检测非标准行为(如 flex wrap 是否真能折行)、CSS 自定义属性是否可被 JS 读取、或需在 JS 中同步做降级逻辑时。
立即学习“前端免费学习笔记(深入)”;
- 纯样式降级(比如用
float备份grid)→ 用@supports - 需配合 JS 动态加 class 或初始化插件 →
Modernizr或手写CSS.supports() - 检测 CSS Houdini /
paint()等实验性 API →CSS.supports()更灵活,因为@supports规则无法在运行时动态插入
CSS.supports() 在 JS 里怎么安全调用
这个静态方法返回布尔值,可用于条件加载资源或切换 class。但它只检测语法层面是否被识别,不保证渲染结果符合预期(比如 CSS.supports('display', 'flex') 返回 true,但旧 Android WebView 的 flex 可能漏掉 align-items)。
典型错误是传入带单位的值却没加引号:CSS.supports('width', '100px') 正确,CSS.supports('width', 100px) 直接报语法错误。
- 第二个参数必须是字符串,哪怕值本身是数字或关键字(如
'auto'、'revert') - 检测自定义属性要用
property语法:CSS.supports('--my-var', 'red') - 检测 @rule(如
@layer)目前不支持,CSS.supports('@layer', 'a')永远返回false - 服务端渲染时该方法不可用,需确保只在客户端执行
哪些 CSS 特性 @supports 压根检测不了
它只管“声明是否被解析”,不管“是否按规范实现”或“是否触发预期效果”。所以这些情况它无能为力:
- 部分实现不完整:比如 Safari 15.4 支持
scroll-behavior: smooth语法,但滚动仍卡顿 ——@supports (scroll-behavior: smooth)仍返回true - 依赖运行时环境:
prefers-reduced-motion是媒体查询特性,不能用@supports检测 - 涉及 DOM 行为:
:has()虽然能被@supports检测,但某些浏览器(如早期 Chrome)支持语法却不支持嵌套复杂选择器,检测通过但实际不生效 - CSS 自定义属性的值是否被 JS 正确设置?
@supports完全不关心
真正难的不是写对检测语句,而是判断「检测通过」之后,那个特性在当前设备上是不是真的能用。有时候得靠真实设备跑一遍,或者留个兜底的 class 来手动覆盖。










