步骤条必须采用语义化HTML结构(如<ol><li>),正确设置aria-current="step",避免破坏焦点流,并通过CSS变量统一管理暗色模式颜色,确保状态、焦点、主题、无障碍全面协同。
步骤条 HTML 结构必须是可语义化遍历的顺序流
很多“美化失败”的根本原因,不是 css 写得不对,而是步骤条的 dom 结构破坏了线性流程。比如用 float 或 position: absolute 打乱了自然文档流,导致 aria-current、键盘 tab 顺序、屏幕阅读器无法正确识别当前步。
实操建议:
- 步骤容器用
<ol>包裹,每步用<li>,这是最稳妥的语义化基础 - 当前步必须设
aria-current="step",不只是加个 class - 禁用
display: none隐藏非当前步——改用visibility: hidden+pointer-events: none,否则会中断焦点流 - 如果用 React/Vue 动态渲染,确保 key 不重用,避免 DOM 复用导致状态错位
CSS 自定义步骤条时别硬改原生表单控件的伪元素
创建表向导(如 Ant Design 的 Steps、Element Plus 的 el-steps)内部常封装了 <input type="radio"> 或 <button>,直接对 ::before/::after 做复杂动画,容易被框架样式覆盖或在 Safari 中失效。
实操建议:
- 优先通过组件提供的
status、finish-status等 prop 控制状态,而不是强行覆盖.ant-steps-item-finish .ant-steps-item-icon - 若必须定制,用属性选择器锚定状态:
[aria-current="step"] .step-icon比.step-item.active .step-icon更可靠 - 避免用
!important覆盖框架样式——改用更高优先级的选择器,比如加一层body .my-steps .ant-steps-item-icon - 圆点/数字图标统一用 SVG 内联,不用 background-image,否则高缩放下模糊且无法响应颜色变量
分步表单中「下一步」按钮状态逻辑常被忽略的三个边界
用户卡在某一步,往往不是样式问题,而是按钮的 disabled 判断漏掉了异步校验、脏检查或字段依赖。
实操建议:
-
disabled状态不能只看当前页字段是否填了,要等所有关联校验 Promise resolve(比如邮箱去重接口返回后才放行) - 切换步骤时,如果上一步有未保存的富文本或文件上传,需主动触发
form.validateFields()或手动比对initialValues和当前值 - 禁用按钮后,仍要监听 Enter 键:用户按回车可能绕过按钮点击,直接提交整个表单
- 移动端需额外处理:iOS Safari 对
:disabled按钮的 focus 样式支持差,建议加tabindex="-1"配合 JS 拦截键盘事件
暗色模式下步骤条颜色变量必须和 form control 同步更新
单独给步骤条写一套 dark 模式 CSS 很容易,但一旦表单内嵌了 DatePicker、Select 等组件,它们的弹层背景色、边框色若没同步变,视觉就割裂了。
实操建议:
- 不要用媒体查询写死
@media (prefers-color-scheme: dark)—— 改用 CSS 自定义属性,比如--step-active-bg: var(--primary-color);,让整套 UI 共享同一组变量 - 检查框架是否提供主题 token(如 Ant Design 的
theme配置),优先走配置驱动,而非手写 CSS - 测试时重点看过渡态:比如从步骤 2 切到步骤 3,步骤 2 的圆点从 active 变成 finish,此时它的颜色应随主题变量实时响应,而不是卡在旧值
真正难的从来不是怎么画个好看的圆点,而是让每一步的状态变更、焦点流转、主题响应、辅助技术支持全部咬合在一起。漏掉其中一环,用户就会在某个不起眼的地方卡住,还找不到原因。

















