bootstrap 5 官方无内置步骤指示器,必须用+语义结构、aria-current属性标记状态、css伪元素生成图标与连线,并同步表单校验及键盘导航。

Bootstrap 5 官方没有 .step、.steps 或任何内置步骤指示器类——你搜到的“一步到位”方案,基本是第三方封装、旧版社区代码,或误把 progress 当步骤条用。真要实现语义正确、响应式、无障碍可用的步骤条,必须用原生 HTML 结构 + 工具类 + 自定义 CSS 组合。
用 nav + ol 搭语义化结构,别套 div 堆砌
步骤条本质是导航控件,不是数值反馈器。必须用 <nav aria-label="表单步骤"></nav> 包裹有序列表,每步为 <li class="nav-item">,链接用 <a class="nav-link"></a>,并靠 aria-current 标记状态:
-
aria-current="step"是唯一被屏幕阅读器识别的“当前进行中”状态;class="active"对辅助技术不可读,也无语义绑定能力 -
aria-current="true"可用于标记“已完成”,但仅当需明确区分“完成”与“进行中”时使用,二者不能混用 - 每个
<a></a>的href必须指向对应表单区域 ID(如#step-2),否则浏览器前进/后退和锚点跳转失效 - 服务端渲染时,
aria-current必须由后端准确输出;React/Vue hydrate 若只靠 JS 补,极易错位
用伪元素 ::before 和 ::after 画图标与连线,别写死宽度
状态图标(圆点、对勾、数字)和连接线必须通过 CSS 生成,避免污染语义结构或小屏错位:
- 图标统一用
.nav-link::before:设为display: inline-block+vertical-align: middle,确保基线对齐;尺寸用1.25rem而非像素值,适配缩放 - 样式由属性驱动:
[aria-current="step"]::before设主色,[aria-current="true"]::before设完成色,:not([aria-current])::before设灰阶未激活色 - 连线用
.nav-item:not(:last-child) .nav-link::after实现,横排时配合flex-grow: 1动态撑开,避免最后一项多画一条线 - 禁用
transform: scaleX()或内联style.width控制连线长度——缩放、动画、断点切换时易卡顿或偏移
响应式断点下必须重置布局和间距,别依赖 gap-* 工具类
小屏竖排不是简单加个 flex-column 就完事,不调细节会导致文字重叠、箭头拉长、点击区域消失:
- @media (max-width: 576px) {
.step-nav{flex-direction: column;gap: 1rem; } } -
.nav-link在移动端建议padding: 0.75rem 1rem+font-size: 0.875rem,防止高度撑开导致行距失衡 - 不要指望
gap-3这类响应式工具类在flex-column下稳定工作——它的断点逻辑和 flex 排列不完全匹配 - 竖排时连线改用
border-bottom,而非border-right,否则会横向溢出
禁用未激活项时,用 tabindex="-1" + pointer-events: none,别碰 disabled
disabled 会直接砍掉键盘焦点和屏幕阅读器可访问性,而步骤条必须支持键盘导航:
- 未激活的
<a></a>应保留可聚焦性(默认行为),仅通过tabindex="-1"移除其在 tab 键顺序中的位置,并用pointer-events: none阻止鼠标交互 - CSS 中需显式覆盖默认
nav-link样式:[aria-current="step"] { pointer-events: auto; },否则当前步也无法点击 - 若某步含异步校验(如用户名可用性检查),按钮进 loading 状态时也需同步设置
tabindex="-1",防重复提交
真正难的不是画出那几个圆点和连线,而是让 aria-current 始终与表单真实状态严格同步——JS 改 UI 很容易,但校验失败后回退、浏览器前进后退、服务端直出与客户端 hydrate 的边界,稍有疏漏就会让读屏软件读错、键盘用户卡死、用户看到“进度已到第 3 步”却连第 2 步的邮箱都没填。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











