用语义化结构实现步骤指示器,配合aria-current="step"标识当前步,确保屏幕阅读器可读;css避免仅用伪元素生成编号,连接线需防布局塌陷;js控制时同步url、title、焦点与滚动,ie11降级用inline-block和svg。

怎么用纯 HTML + CSS 实现可访问的步骤指示器
原生 HTML 没有 <step></step> 或 <progress-indicator></progress-indicator> 标签,所谓“HTML 步骤指示器”本质是语义化结构 + CSS 视觉增强。关键不是“怎么画圆点”,而是“怎么让屏幕阅读器知道当前第几步、哪些已完成、哪步在焦点上”。
- 用
<ol></ol>包裹步骤项,天然表达顺序和计数,aria-current="step"标明当前步 - 每个
<li>里放<span></span>或<strong></strong>做视觉编号,别只靠 CSS 伪元素生成数字(否则读屏器可能跳过) - 禁用
<div> 堆砌步骤——它不传递顺序语义,键盘 Tab 顺序也容易错乱 <h3>CSS 画步骤线时为什么连不上?常见断点原因</h3> <p>多数人用 <code>::before/::after画连接线,但线“断开”往往不是样式写错,而是布局塌陷或定位失效。- 父容器没设
position: relative,导致子元素absolute定位漂移 - 步骤项用了
display: flex但没设flex: 0 0 auto,缩放或内容变长时挤压间距,线坐标偏移 - 用
transform: translateX()移动线段时,未配合will-change: transform,某些浏览器渲染丢帧造成视觉断裂 - 移动端横屏时,
vw单位计算的线长没随视口重算,需用 JS 监听resize微调或改用calc()
JavaScript 控制步骤跳转时,
history.pushState和直接改 DOM 的取舍用户点击某步跳转,该不该改 URL?取决于是否需要前进/后退、分享链接、SEO。
- 要支持浏览器原生导航:用
history.pushState()+ 监听popstate,同时更新aria-current和焦点状态 - 纯表单向导(如注册三步走),且不允许返回上一步:直接操作 DOM 类名 +
tabindex,避免历史栈污染 - 千万别只改 UI 不同步
document.title——屏幕阅读器靠它感知步骤变化,例如把 “步骤 2:填写信息” 写进 title - 用
scrollIntoView({ block: 'nearest' })滚动到当前步骤区域,但加if (window.matchMedia('(prefers-reduced-motion)').matches)判断是否跳过动画
IE11 兼容下步骤指示器的底线方案
IE11 不支持
flex多行对齐、grid、transform3D、aria-current识别率低,得降级但不能放弃语义。立即学习“前端免费学习笔记(深入)”;
- 用
display: inline-block+vertical-align: top替代 flex 布局,宽度用%配合box-sizing: border-box - 连接线改用背景图(
background-image: linear-gradient())或 SVG<svg><line></line></svg>内联,避免 IE 对伪元素定位的 bug -
aria-current在 IE 中无效,补上role="status"+ 动态更新文本内容,例如<span role="status">当前步骤:2</span> - 禁用所有
transition和@keyframes,IE11 的重排性能差,动画卡顿会掩盖步骤逻辑
最易被忽略的是焦点管理:每切换一步,必须用
element.focus()把键盘焦点移到当前步骤容器,否则键盘用户会迷失在页面中间。这不是“锦上添花”,是 WCAG 2.1 里明确要求的可操作性底线。 - 父容器没设









