轮播每次配键盘无障碍都要写几百行JS——Chrome 154用三行CSS把这件事彻底原生化了
做轮播和标签页的时候,实现键盘可访问性一直是个脏活累活。
你得给每个标记写 `role=”tab”`、给面板写 `role=”tabpanel”`、给容器写 `role=”tablist”`;然后自己写 JavaScript 监听方向键,实现 roving tabindex;最后还得记得给非活动面板加上 `aria-hidden=”true”` 或者 `inert`,把它们从无障碍树里摘掉。整一套下来,几百行代码是少的。
Chrome 154 稳定版里,scroll-marker-group 多了 tabs 模式,让这件事完全变成 CSS 的活儿。
## 声明即语义:浏览器帮你把 ARIA 写完了
用起来很简单,在滚动容器上声明 `scroll-marker-group: after tabs`,然后给每一项加上 `::scroll-marker`:
“`html
“`
“`css
.carousel {
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-marker-group: after tabs;
}
section::scroll-marker {
content: “”;
/* 做成圆点 */
width: 10px;
height: 10px;
border-radius: 50%;
background: #ccc;
}
/* 标记当前活动面板 */
section::scroll-marker:target-current {
background: #1a73e8;
}
“`
就这么几句,浏览器会自动给你生成对应的 ARIA 语义:滚动容器获得 `tablist` 角色,每个标记获得 `tab` 角色,每个面板元素获得 `tabpanel` 角色。你不需要写任何 `role` 属性。
## tabs 模式的键盘行为,浏览器全包
这是最关键的部分。tabs 模式下,键盘交互是原生级的:
– **只有当前活动的 `::scroll-marker` 是 Tab 停靠点**,你按一次 Tab 就能进到当前面板的内容里
– **左右方向键在标记之间跳转**,和你用鼠标点标记效果完全一样
– **非活动面板的内容自动从无障碍树里移除**,不需要你手动加 `aria-hidden`
这就解决了以前一个很头疼的问题:你用 JavaScript 实现的 roving tabindex,每次面板数量变了都得重新绑定事件。tabs 模式完全由浏览器维护这个状态,你只管改 HTML。
## 和 links 模式怎么选
scroll-marker-group 有两种模式:
– `links`(也是默认值):标记是 `link` 角色,每个标记都是顺序 Tab 停靠点,激活后焦点跳到目标元素。适合产品卡片、文章章节、图片画廊——所有内容都在同一个可滚动文档里
– `tabs`:标记是 `tab` 角色,只有当前活动标记是 Tab 停靠点,方向键导航,inert 非活动面板。适合真正的标签页界面,每一屏内容是独立的
两种模式都是纯 CSS,不需要任何 JavaScript。
## 现在能用在生产环境吗
Chrome 154 桌面版已在 2026 年 9 月 22 日稳定发布。Firefox 和 Safari 还没支持,scroll-marker-group 本身目前是 Chromium only。
渐进增强的思路是:
“`css
/* 默认:不用标记点,改用 dot 指示器 */
.carousel-indicator {
/* … */
}
/* 有支持时:让浏览器接管标记和交互 */
@supports (scroll-marker-group: tabs) {
.carousel {
scroll-marker-group: after tabs;
}
.carousel-indicator {
display: none; /* 隐藏旧指示器 */
}
}
“`
在不支持的浏览器里用户看到的是普通滚动容器,带你自己的 dot 指示器;在 Chrome 154 里自动获得完整的键盘可访问性和 ARIA 语义。
## 下一步
如果你现在在做轮播组件,第一件事是检查你的键盘可访问性实现是否完整——roving tabindex 有没有正确实现,面板内容有没有从无障碍树里移除。Chrome 154 之后,这两个问题用三行 CSS 就能解决。
具体可以看 Chrome Platform Status 的 scroll-marker-group 说明和 W3C CSS Overflow Level 4 规范。
评论区
登录后可评论。