你以为 @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() 是它第一次学会「告诉你它内部发生了什么」。

评论区

0 条评论

登录后可评论。