用实现语义化响应式步骤条,通过aria-current、data-step-id精准控制状态,伪元素绘线,兼顾可访问性、键盘导航与移动端触摸体验。

怎么用纯 HTML + CSS 实现响应式步骤条
纯靠 <ol></ol> 和 <li> 搭配 CSS 伪元素就能做出语义清晰、可访问、不依赖 JS 的步骤条。关键不是“画线”,而是让每个步骤有明确的完成状态和视觉反馈。
常见错误是直接用多个 <div> + 绝对定位硬拼,结果屏幕阅读器读不出顺序,缩放后线条错位,移动端点击区域过小。
<ul>
<li>用 <code><ol></ol> 包裹步骤,保证 DOM 顺序即逻辑顺序,aria-current="step" 标记当前步
<li> 内部结构统一:<span class="step-number"></span> + <span class="step-label"></span>
::after 生成,宽度设为 100% 并配合 transform: translateX(-100%) 避免首项左侧多出半截线user-select: none —— 否则 Safari 下双击文字会意外选中整条线如何动态更新步骤状态(不用框架)
状态切换本质是切换 class:给已完成步骤加 is-complete,当前步加 is-current,未开始的保持默认。不要用内联 style 改颜色或 visibility,破坏可维护性。
典型场景:表单分步提交,用户点“下一步”时需校验并推进状态。这时候容易踩的坑是直接操作 document.querySelectorAll('li') 然后硬写 index,结果步骤增减后逻辑全崩。
立即学习“前端免费学习笔记(深入)”;
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 用
data-step-id属性标识每步唯一 ID,比如data-step-id="address" - 状态更新函数接收目标 ID,用
querySelector('[data-step-id="address"]')精准定位,不依赖序号 - 切换前先清除所有
is-complete和is-current,再按规则重设 —— 避免残留 class 导致样式冲突 - 如果步骤数超过 5,建议加
tabindex="0"到每个<li>,支持键盘导航
为什么 progress 元素不适合做多步骤导航
<progress></progress> 是为“任务进度百分比”设计的,语义上只表达“已完成多少”,无法描述“第几步、叫什么、是否可回退”。W3C 明确指出它不适用于步骤向导类 UI。
实际用 <progress value="2" max="4"></progress> 会触发两个问题:一是辅助技术把“2/4”读作“百分之五十”,丢失步骤名称;二是无法给中间某步单独加图标或链接。
- 想兼容无障碍?必须用
<ol></ol>+aria-label或aria-labelledby - 需要跳转?每个
<li>内必须包裹可聚焦元素(如<button></button>或带tabindex的<span></span>),不能只靠 click 事件监听 - 动画需求?用
transition: opacity .2s, transform .2s控制状态变化,别用animation循环播,干扰用户注意力
移动端适配最容易忽略的三个细节
步骤条在手机上不是简单缩放就行。横向空间紧张时,文字换行、图标对齐、触摸热区都会出问题。
- 给
.step-label加white-space: normal,避免长文本溢出容器;配合max-width: 80vw防止撑破布局 - 步骤编号圆圈用
min-width和min-height固定尺寸(比如2rem),别用em或百分比,否则字体缩放时变形 - 触摸目标至少
44px × 44px—— 给<li>设padding: 0.75rem,内部span用display: inline-block扩展点击区域
步骤条真正的难点不在“怎么画出来”,而在状态同步的可靠性、键盘与触控的一致性、以及当步骤动态增减时 DOM 结构不崩溃 —— 这些地方一漏,用户卡在第三步点不动,排查起来比重写还费时间。


















