纯css可实现语义化、无障碍、响应式的步骤条:用结构配合data-status三态控制高亮,::before精准定位画线,flex布局加min-width:0防文字撑开,visibility:hidden保兄弟关系连续。

纯 CSS 就能实现步骤条并高亮当前进度,不需要 JS 控制样式计算——关键在结构语义化、状态驱动和伪元素精准定位。
用 <ol></ol> 而不是 <div> 包裹步骤项
<p>步骤有天然顺序,<code><ol></ol> 让屏幕阅读器正确读出“第1步、第2步”,也方便用 CSS 计数器生成序号。硬套 <div> 会丢失语义,后期加无障碍支持成本翻倍。
<ul>
<li>每个步骤用 <code><li>,不要嵌套额外容器
class="step step--done"、class="step step--active" 或 data-status="active" 标记状态,别只靠序号推断li 设固定宽度(如 width: 25%),响应式下文字换行会导致高度错位
.step:not(:first-child)::before 画连接线时 left: -50% 是关键
连接线必须从上一个节点中心连到当前节点中心,否则多一步或少一步就偏移。用 ::before 在非首项上画线,配合 left: -50% + transform: translateY(-50%) 才能对齐。
- 错误写法:
.step::before—— 第一个节点左边会多出一根悬空线 - 错误写法:
left: 0—— 线条起点贴左边界,不指向前一节点中心 - 必须加
position: relative到.step,否则::before的绝对定位会相对于 body
三态高亮靠 data-status 属性选择器,不是 class 切换整条线
用 data-status="done"、data-status="active"、data-status="todo" 配合属性选择器控制颜色和图标,比手动改多个 class 更可靠,也避免漏掉某一段连线样式。
-
[data-status="done"]::before:绿色实心圆点 + 粗连接线 -
[data-status="active"]::before:蓝色描边圆点 + 连线延伸到当前节点 -
[data-status="todo"]::before:灰色空心圆点 + 不画右侧连线(用:not(:last-child)控制) - 进度线颜色由前一项的
data-status决定,比如[data-status="done"] + li::before才设绿色背景
Flex 布局等分节点必须配 min-width: 0
display: flex + justify-content: space-between 是最稳的横向布局,但子项若含长文本,默认会撑开导致间距崩坏。加 min-width: 0 强制收缩,才能让 flex: 1 真正生效。
- 父容器:
.steps { display: flex; justify-content: space-between; } - 子项:
.step { flex: 1; min-width: 0; text-align: center; } - 不加
min-width: 0时,iOS Safari 和旧版 Chrome 可能完全不收缩,文字溢出或换行后节点高度不一致
真正容易被忽略的是:连接线的视觉连续性依赖相邻兄弟关系,一旦中间某个 li 被 JS 动态移除或隐藏(比如用 display: none),+ li 或 :not(:first-child) 就会跳步——这时候得用 visibility: hidden 替代,或者重写状态逻辑。











