算了,还是讲下named-feature() @supports规则检测吧

这篇文章发布于 2026年10月26日,星期一,15:09,归类于 CSS相关。 阅读 79 次, 今日 79 次 没有评论

 

一、一步到位

今天介绍一个特殊的@supports检测函数,那就是named-feature(),目前就下面两个经典用法:

/* 检测:锚点定位是否感知 transform(transform后锚点位置跟着变) */
@supports named-feature(anchor-position-follows-transforms) {
  /* 支持该行为时,启用高级锚点布局 */
  .tooltip {
    position: anchor(--btn);
  }
}

/* 检测单轴滚动容器能力 */
@supports named-feature(single-axis-scroll-container) {
  .scroll-x {
    overflow-x: auto;
    overflow-y: clip;
  }
}

有别于之前的(property: value)属性检测、selector(:has())选择器检测、at-rule(@container) AT规则检测。

这里的named-feature()检测的函数参数是CSS规范里显式登记的特殊名字。

二、为何需要?

先说anchor-position-follows-transforms。

锚点定位 anchor() 有一个大坑,那就是部分旧版实现,元素做 transform 之后,锚点是坐标不会跟着更新的。

锚点定位是非常强悍的CSS特性,很好用,好用的不得了,有兴趣可以访问我之前的文章:全新的CSS Anchor Positioning锚点定位API

如果使用传统语法检测,比方说@supports (position: anchor()),结果只能检测浏览器认识 anchor 语法与否,并不能检测transform定位bug浏览器是否修复。

所以,就必须用 named-feature(anchor-position-follows-transforms) 判断行为是否符合预期,以此区分两套实现逻辑,避免 UI 错位。

那single-axis-scroll-container呢?

说起单轴滚动,就不得不提我上个月写的这篇文章:一个视频彻底看懂CSS scroll-axis-lock none的作用

虽然都是轴滚动相关的特性,但这里的检测背景和作用与之还有所不同,这个值得展开说说。

三、单轴溢出的问题

比方说设置一个表格可以水平和垂直滚动,结构如下:

<div class="table-wrapper" style="overflow-x: auto;">
  <table>
    …
  </table>
</div>

然后希望表头和第一列粘性定位:

.table-wrapper thead {
  position: sticky;
  top: 0;
}

/* 第一列也粘性定位*/
.table-wrapper td:first-child {
  position: sticky;
  left: 0;
}

结果怎么着,水平滚动是有粘性定位效果的,但是垂直滚动就没有。

为何?

这是一个“次轴无法被彻底裁剪”历史遗留问题。

长期以来,CSS overflow 的组合存在限制。

如果你设置了 overflow-x: auto,哪怕将 overflow-y 显式设为 clip 或 hidden,浏览器在底层计算滚动上下文时,仍然会将该容器视为两个轴向都能滚动的容器(或者说,计算逻辑仍会将其视为 overflow-y 产生了滚动边界)。

插播一下,如果不知道overflow:clip的作用,可以看我很多年前写的这篇文章:CSS overflow-clip-margin属性简介

于是乎,大表格的粘性定位就成了受害者。

浏览器会误认为该外层容器在 Y 轴也是滚动容器,从而导致表头被困在外层容器中,无法跟随页面垂直滚动条实现粘性固定(这句话不理解也没关系,AI时代了,细节原理不重要了)。

效果见下面录屏示意(不动点击播放),左侧是有问题的,右侧是目标效果,左侧可以看到本该粘性定位的表格头直接被滚走了。

停顿了片刻……

算了,还是有不少好学的小伙伴的,上面这句话再通俗解释下吧。

就是我特么的只设置了水平滚动,垂直方向我压根没有任何滚动,你不能傻乎乎的看到我是个滚动容器,就不让我垂直方向的表头无法粘性定位吧!

PS:粘性定位的启动点计算是根据第一个滚动容器来的,详见此文:深入理解position sticky粘性定位的计算规则

为了解决该问题,CSS 规范进行了修订,允许 overflow-x: auto 与 overflow-y: clip(或通过简写 overflow: auto clip)配对时,容器仅充当单轴(X轴)滚动容器。

此时,Y 轴的 position: sticky 就可以绕过该容器,正确地去跟踪文档(页面)的垂直滚动条。

根据我从chrome开发者官方页面看到的数据,貌似是Chrome 154开始支持的。

而为了检测浏览器是否开始了单轴滚动的支持,就需要用到这里的named-feature(single-axis-scroll-container)检测。

为什么不能直接用 @supports (overflow: auto clip)?

  • 如果仅用 @supports (overflow: auto clip),浏览器只会检查自己能不能解析这个语法。
  • 很多旧版本浏览器虽然能解析这个语法,但其底层的滚动上下文计算机制仍然是旧的,并不会正确处理修订后的单轴滚动逻辑。

所以这里才需要@supports named-feature(single-axis-scroll-container)检测浏览器是否已经支持了overflow:clip与浏览器单轴滚动。

如果不支持,我们可以使用JS打个补丁,或使用其他策略修复。

演示页面

对了,演示页面差点忘记了,如果你的浏览器Chrome版本154及其以上,可以狠狠地点击这里:CSS单轴滚动容器的怪异行为以及修复demo


四、结语碎碎念

named-feature()特征检测其实没什么好讲的,因为太小众了,我估计全中国,99.9%的前端都没有机会在实际项目中使用此特性。

那为什么还专门写一篇文章呢?

主要是这两个特征检测背后的故事很有意思,值得念叨。

一般named-feature()特征检测都是检测浏览器之前有某某渲染问题,在之后的版本中修改了策略,或者修复了bug,然后针对这个现象,专门弄个白名单机制一个的特殊名称。

方便开发者更好地对新老特性做兼容。

很好的设计想法。

但是太小众,AI时代的前端开发者普遍没什么学习热情,怎么可能学这种东西,狗都不学。

接下来看下此特性的兼容性,看图:

named-feature()兼容性

哇,好新的特性啊。

星星眼

得,更是没什么学习价值了。

😮‍💨😮‍💨😮‍💨

好,就说这多,我们下周再见!

飞吻再见

(本篇完)

分享到:


发表评论(目前没有评论)