<p>纯CSS步骤条用::before画圆点、::after画连接线,需父元素设position: relative;连接线用calc(100% - 16px)适配;状态靠class控制,点击区域须由真实可交互元素承载。</p>

步骤条用伪元素画圆点和连接线,比写 HTML 更轻量
纯 CSS 实现步骤条时,::before 和 ::after 是最常用也最容易出错的两个入口。它们不增加 DOM 节点,但必须配合 position: relative 的父容器才能准确定位;否则圆点飘走、连线错位是常态。
关键前提是:每个步骤项(如 .step-item)得设为 position: relative,否则 ::before 会相对于最近的定位祖先定位,很可能跑到页面顶部去。
-
::before通常画圆点(content: ""+border-radius: 50%),宽高设为固定值(如16px) -
::after通常画右侧的连接线(width: 100%或具体像素值),但注意它默认从父元素左边界开始,若要右对齐需加right: 0和transform: translateX(-100%) - 别忘了给
::before和::after都加上content: "",否则完全不渲染
响应式断点下连接线长度怎么动态算?别硬写百分比
常见错误是给 ::after 设 width: 80%,结果在小屏上连不到下一个圆点——因为百分比基于父容器宽度,而步骤项本身在 flex 布局里宽度不固定。
更可靠的做法是:让所有步骤项用 flex: 1 均分容器宽度,再用 ::after 绘制「从当前项右边缘到下一项左边缘」的线。这需要把连接线逻辑交给最后一个非末尾项:
立即学习“前端免费学习笔记(深入)”;
- 给
.step-item:not(:last-child)::after画线,避免末尾多出一条空线 - 设
width: calc(100% - 16px)(假设圆点直径 16px),这样线长 = 当前项宽度 − 圆点半径,视觉上刚好顶到下一个圆点左侧 - 小屏下可改用
display: block垂直堆叠,此时::after改为画下方短线(height: 2px),并用margin-top: 8px控制间距
active 状态用 class 切换,别依赖 :nth-child
步骤条的状态(当前步、已完成、未开始)必须由 JS 控制 class,比如 .step-item.is-active。千万别用 :nth-child(2) 这类静态选择器来标“第二步”,否则用户跳步或后端返回步骤数不固定时直接失效。
伪元素的状态样式应绑定到 class 上:
-
.step-item.is-active::before→ 改背景色、加图标(content: "✓")、提升z-index -
.step-item.is-finished::before→ 同样改色,但::after也要同步变色(.is-finished::after) - 禁用状态建议加
opacity: 0.5和pointer-events: none,而不是只改颜色
移动端点击区域太小?伪元素无法响应点击
::before 和 ::after 是装饰性内容,天生不响应鼠标事件。如果步骤条支持点击跳转,必须确保点击区域落在实际的 HTML 元素(如 <button> 或带 role="button" 的 <div>)上,而不是指望点中那个 12px 的圆点。
实操建议:
- 把步骤项标签设为
<button type="button">,语义正确且自带焦点/键盘支持 - 圆点和连线用伪元素画,但整个按钮的
padding至少留12px,保证手指能点中 - 如果用
<div>,务必加tabindex="0"和role="button",否则屏幕阅读器不可见
伪元素不是万能的画布,它不参与交互流。该用真实元素承载行为的地方,一步都不能省。


















