根本原因是多个步骤共用同一css变量未隔离作用域,必须为每个步骤容器独立设置--step变量并用calc(var(--step)*1%)计算宽度,transition须作用于实际变宽元素。

为什么分步表单进度条总不同步
根本原因不是 JS 没更新,而是多个步骤共用同一组 CSS 变量却没隔离作用域。比如所有步骤容器都读 --step,JS 却只改了某个父节点的 style.setProperty('--step', '2'),其余步骤仍卡在旧值——变量没“绑定到每个步骤实例”,而是被全局或父级覆盖。
每个步骤容器必须独立挂载变量
不能把 --step 定义在 :root 或外层 .form-wizard 上,否则所有步骤读的是同一个值。正确做法是:每个步骤容器(如 <section class="step"></section>)自身带变量声明。
- HTML 中给每步加唯一标识:
<section class="step" data-step="1"></section>、<section class="step" data-step="2"></section> - CSS 初始化每个容器:
.step { --step: 0; },不写:root { --step: 0; } - JS 更新时精准定位:
step2El.style.setProperty('--step', '1'),不是formEl.style.setProperty
width 计算必须用 calc() 避免单位拼接失败
width: var(--step) % 一定无效——CSS 解析器不会把字符串 "1" 和 % 拼起来,整个声明直接丢弃。必须让 calc() 承担单位注入。
- ✅ 正确写法:
width: calc(var(--step, 0) * 1%),其中--step存纯数字(如1),1%提供单位 - ❌ 错误写法:
width: var(--step, 0%)→ fallback 是0%,但0% * 1%合法吗?不合法,计算崩溃 - ⚠️ 注意:如果步骤总数是 5,当前步是第 3 步,
--step应设为60(即3/5*100),不是3,否则宽度永远 ≤ 20%
transition 必须写在进度条元素本身上
常见错误是把 transition: width 0.3s 写在表单容器或步骤容器上,但真正变宽的是内部的 .progress-fill 元素。浏览器只对实际变更的属性做插值,父级声明无效。
- 确保
.progress-fill有明确初始宽度:width: 0%,不能是auto或未声明 - 检查 computed 样式:打开开发者工具,选中
.progress-fill,看width是否随--step实时变化 - 若用伪元素实现填充(如
.progress::before),transition 也得写在该伪元素规则里,不是主元素
同步逻辑真正卡点不在 JS 调用频率,而在变量作用域是否落到每个视觉单元上——漏掉一个 style.setProperty 调用,或错把变量挂到父级,整个进度条就停在那儿不动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











