你以为 @supports 只能检测 CSS 属性名和值?今天它连「浏览器内部行为」都会告诉你了
写过 CSS 的人都熟悉这套写法:
@supports (display: flex) {
.card { display: flex; }
}
查属性名、查值,这是 @supports 一直能做到的。但有一类情况它一直无能为力:两个旧属性突然开始协同工作,或者底层实现变了,但语法完全没变。这类变化,你根本不知道浏览器内部发生了什么。2026 年 8 月,@supports named-feature() 把这件事彻底变了。
问题的根子:@supports 只能检测「语法」,检测不了「行为」
举一个经典例子。2020 年,Chromium 实现了 Flex 布局的 gap 属性(gap: 1em)。当时你想检测「浏览器是否支持 flex + gap 组合」,@supports 会这样回答:
@supports (display: flex) and (gap: 1em) { /* ... */ }
但这根本不管用。浏览器会诚实地告诉你:「gap?我认识;flex?我认识。」至于它俩一起用能不能工作,它不负责验证。原因是 @supports 只做语法解析检测,不验证组合行为。
同样的问题在 transform-aware anchor positioning 也出现过。CSS 锚点定位最初发布时,不考虑锚点元素上的 transform 变化——你给按钮加了个 transform: rotate(10deg),弹层就漂了。后来 Chrome 144 修复了这个问题,但语法没变,anchor-name: --x 仍然有效,旧的 @supports 查不出来。
这类「实现变化、语法不变」的场景,过去没有标准检测手段,要么靠 UA 字符串判断,要么靠经验加 try/catch。
named-feature():把浏览器内部行为变成可检测的特征
@supports named-feature() 是 CSS 条件规则的新成员,专门解决「行为级」特性检测。它的参数不是属性值,而是一个预定义的特征关键字:
@supports named-feature(anchor-position-follows-transforms) {
/* 只有当浏览器真正支持 transform-aware anchor positioning 时才生效 */
.tooltip {
position: fixed;
position-anchor: --trigger;
transform: rotate(var(--angle)); /* 现在安全了 */
}
}
这些关键字不是随意起的,而是由 CSS Working Group 统一维护、只有真正重要的行为变化才配拥有姓名。这是关键区别:不是给你自定义的,是给那些「不得不单独列出」的实现变化准备的。
目前两个真实用例:transform-aware anchor 和 sticky 轴困
用例一:transform-aware anchor positioning
CSS 锚点定位(anchor positioning)允许把 tooltip 拴在按钮上,纯 CSS 完成定位,不需要任何 JS 库。但最初的实现忽略锚点元素的 transform——你给按钮加了旋转,tooltip 就找不着北了。
这个问题在 Chrome 144 修复了(2025 年 11 月),Safari 27 正式支持,Firefox 156 也即将同步支持。问题是:你的代码怎么知道当前浏览器修没修这个?
旧方法:靠经验判断,或者 UA 字符串盲猜。
新方法:
@supports named-feature(anchor-position-follows-transforms) {
/* 只有浏览器真正处理了 transform-aware anchor 时才走这里 */
.tooltip { position: fixed; position-anchor: --btn; }
}
用例二:单轴滚动容器(Single-Axis Scroll Container)
这是另一个长期痛点:你想让一个容器只做水平滚动,但 position: sticky 经常被另一个轴的滚动容器截胡。Chrome 153 开始处理这个问题。但语法上什么都不变——overflow: scroll clip 看起来完全正常。旧 @supports 毫无办法。
现在可以:
@supports named-feature(single-axis-scroll-container) {
/* 单轴滚动容器已修复,sticky 不再被正交轴困住 */
.header { position: sticky; top: 0; }
}
浏览器支持现状
| 特性关键字 | Chrome | Firefox | Safari |
|---|---|---|---|
anchor-position-follows-transforms |
150+ ✅ | 156 即将 ✅ | 27 TP ✅ |
single-axis-scroll-container |
153+ ✅ | — | — |
named-feature() 本身:Chrome 150+、Edge 150+、Opera 134+ 全球覆盖率约 59%。Firefox 155+、Safari 27 也在路上。
下一个该出现的关键字是什么
Bram.us(CSS 领域知名作者、也是这两个关键字的提出者)提过:Style Queries 迟早也要有专属关键字。Style Queries 允许用容器自定义属性的值做条件判断,但 Chrome 111 就支持了,Safari 17 也支持了——现在加关键字反而会产生大量误判(因为老版本也会匹配)。
这说明 CSS Working Group 在给 named-feature() 定关键字这件事上非常克制:只在真的无法用其他方式检测、且开发者真的需要知道的时候才加。
下一步:现在就加一行渐进增强
如果你现在正在用 anchor positioning,马上加一行:
/* 先保证基础定位正常 */
.tooltip { position: fixed; top: 0; }
/* 只有当 transform-aware anchor 真的可用时才启用精确跟随 */
@supports named-feature(anchor-position-follows-transforms) {
.tooltip {
position: fixed;
position-anchor: --trigger;
position-area: top;
}
}
如果你在做响应式布局,用到了 sticky 和 overflow 交叉的场景,加这个检测:
@supports named-feature(single-axis-scroll-container) {
.sticky-header { position: sticky; top: 0; }
}
两行代码,换来的是:旧浏览器用保守方案,新浏览器用最优方案,不需要 JS,不需要 UA 判断,不需要任何运行时检测。
CSS 在变得越来越聪明,而 named-feature() 是它第一次学会「告诉你它内部发生了什么」。
评论区
登录后可评论。