CSS ::scroll-button 怎样给横向滚动列表添加原生箭头
来源:17golang原创
时间:2026-11-07 00:30:31 277浏览 收藏
如果横向卡片列表已经可以滚动,但还想给用户一个清晰的“向前/向后”入口,可以把滚动容器交给 CSS 的 ::scroll-button() 伪元素。它会在滚动容器内部生成按钮,方向由 left、right 等参数决定,不需要为箭头再写一组 JavaScript 点击逻辑。
最小做法是:让列表成为横向滚动容器,再分别给::scroll-button(left)和::scroll-button(right)设置非none的content。按钮会随着可滚动范围自动进入可用或 disabled 状态;同时要保留原生滚动和键盘焦点作为降级入口。
官方地址:https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Overflow/Carousels
下面只讨论横向列表、前后按钮、可访问名称和状态样式,不把 ::scroll-marker 导航或 JavaScript 轮播控制混进来。
先确定 scroll container 与生成条件
::scroll-button() 的前提不是“页面上有一排卡片”,而是目标元素本身要形成滚动容器。横向列表通常需要 display:flex、不换行和 overflow-x:auto;当内容宽度超过容器时,按钮才有实际的滚动空间。
第二个关键点是生成条件:伪元素的 content 不能是 none。只写选择器而不提供内容,浏览器不会创建可交互按钮。这个判断也解释了为什么示例同时设置箭头符号和文本替代。

分别生成 left 与 right 按钮
方向参数表达的是滚动方向,而不是按钮摆放位置。对常见的横向列表,可以把起点方向交给 left,把终点方向交给 right。按钮图标只是视觉提示,真正的滚动语义由伪元素参数决定。
.card-list {
display: flex;
flex-wrap: nowrap;
gap: 1rem;
overflow-x: auto;
scroll-behavior: smooth;
/* 保留原生横向滚动,兼容时仍然可以拖动或使用键盘。 */
scrollbar-width: thin;
}
.card-list::scroll-button(left) {
content: "‹" / "向左滚动";
}
.card-list::scroll-button(right) {
content: "›" / "向右滚动";
}
.card-list::scroll-button(*) {
inline-size: 2.25rem;
block-size: 2.25rem;
border: 1px solid #b8c8dc;
border-radius: 999px;
background: #ffffff;
color: #17324d;
cursor: pointer;
/* 让按钮和卡片列表之间保留明确的视觉层次。 */
box-shadow: 0 0.25rem 0.75rem rgb(23 50 77 / 14%);
}
这里用 ::scroll-button(*) 统一设置两个按钮的外观,再用具体方向选择器提供不同图标。content 右侧的字符串是可访问名称的文本替代,避免只给辅助技术暴露一个不明确的符号。
补齐可访问性与状态样式
生成出来的按钮仍然是交互入口,不能只依赖颜色或箭头形状。键盘用户需要明确的焦点轮廓;当列表已经到达某一侧边界时,浏览器会把对应方向的按钮设置为 :disabled,此时视觉上应降低强调,并取消指针手势。
.card-list::scroll-button(*):focus-visible {
outline: 3px solid #f0a33a;
outline-offset: 3px;
/* 高对比焦点轮廓不改变按钮的滚动职责。 */
}
.card-list::scroll-button(*):hover {
background: #eef6ff;
}
.card-list::scroll-button(*):disabled {
opacity: 0.32;
cursor: default;
/* 到达滚动边界后,按钮保留位置但表达不可继续滚动。 */
}
@media (prefers-reduced-motion: reduce) {
.card-list {
/* 用户要求减少动画时,切回即时滚动。 */
scroll-behavior: auto;
}
}

:disabled 是状态反馈,不是业务代码主动维护的布尔变量。不要再用 JavaScript 监听滚动位置去重复计算同一件事;如果还需要显示页码、当前卡片或滚动标记,那是另一个交互需求,应单独设计。
兼容与降级边界
::scroll-button() 属于较新的 CSS 轮播能力,不应当成为唯一的可用路径。基础列表要先保证在没有伪元素支持时仍可横向滚动;箭头只是增强入口,不能通过隐藏滚动条、禁止触摸滑动或依赖唯一的点击事件来替代基础体验。
可以把增强样式放进能力查询,并保留容器本身的 overflow-x:auto:
@supports selector(.card-list::scroll-button(right)) {
.card-list::scroll-button(left),
.card-list::scroll-button(right) {
/* 只有支持该选择器时,才启用增强按钮的布局和外观。 */
display: inline-grid;
place-items: center;
}
}
@supports not selector(.card-list::scroll-button(right)) {
.card-list {
/* 不支持时继续提供可滚动区域,不伪造一个失效箭头。 */
overflow-x: auto;
scrollbar-width: auto;
}
}
降级时最重要的结果不是“看起来仍有两个箭头”,而是用户仍然能发现列表可以横向移动。真实项目还应结合目标浏览器版本做兼容性决策,但不需要为了使用这个新伪元素重写整个轮播组件。
几个容易混淆的边界
| 问题 | 应当怎样判断 |
|---|---|
| 按钮没有出现 | 先确认选择器挂在滚动容器上,再确认对应 content 不是 none。 |
| 按钮出现但不能继续滚动 | 检查内容是否真的超出容器,以及当前方向是否已经到达边界。 |
| 只显示箭头没有名称 | 给 content 提供文本替代,并保留清晰的焦点轮廓。 |
| 不支持新特性怎么办 | 保留 overflow-x:auto、触摸滚动和键盘路径,把按钮作为可选增强。 |
总结
给横向滚动列表添加原生箭头的关键是把职责分开:滚动容器负责产生可移动的内容范围,::scroll-button(left/right) 负责提供方向入口,content 负责触发生成并补充名称,:focus-visible 和 :disabled 负责让交互状态可感知。先保留基础滚动,再叠加这层 CSS 增强,兼容和可访问性会更稳。
相关问题
为什么只写 ::scroll-button(right) 没有按钮?因为生成伪元素还需要对应选择器的 content 为非 none,仅声明选择器不会自动创建控件。
::scroll-button() 和 ::scroll-marker 是一回事吗?不是。前者是滚动方向按钮,后者用于把子项或分页位置组织成滚动标记,两者解决的导航层级不同。
能不能完全隐藏横向滚动条?可以有视觉设计上的处理,但不应因此丢失触摸、键盘或其他可发现的滚动入口;新伪元素不支持时尤其要保留原生滚动。
-
424 收藏
-
130 收藏
-
414 收藏
-
427 收藏
-
163 收藏
-
313 收藏
-
337 收藏
-
145 收藏
-
450 收藏
-
437 收藏
-
488 收藏
-
232 收藏
-
343 收藏
-
404 收藏
-
390 收藏
-
102 收藏
-
147 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习