必须将.progress内嵌于每个.nav-link中,否则小屏下会出现进度条截断、文字重叠、高度错乱;正确做法是每项包含标题、描述、进度条三部分,用flex-column gap-2布局,并在移动端媒体查询中重置gap、align-items和width以确保对齐与响应性。

直接用 nav + flex-column + 内嵌 progress 就能实现,但必须把进度条塞进每个 nav-link 里,不能放外面——否则小屏下进度条被截断、文字重叠、高度错乱。
为什么不能把 .progress 放在 nav 外面
常见错误是写成:<nav><ol>...</ol>
<div class="progress">...</div></nav>。这种结构在移动端会出三个问题:
- 进度条脱离语义上下文,屏幕阅读器无法关联到当前步骤
-
nav默认 flex-column 后,外部.progress容器高度塌陷或被裁剪(尤其配合overflow: hidden的父容器) - 文字换行时,
.progress的width按父容器算,但父容器宽度在竖排下不稳定,导致进度条忽长忽短
每步内嵌 progress 的正确写法
每个 nav-item 里,nav-link 要包裹标题、描述、进度条三部分,用 flex-column gap-2 控制间距:
填写基本信息
请确认姓名与联系方式
-
h-1(4px 高)比h-2更稳,避免小屏下进度条过粗压字 - 宽度用
style="width: X%"或 CSS 变量(如style="width: var(--step-progress, 0%)"),别用progress-bar-animated——它和步骤逻辑无关,还可能干扰 JS 控制 - 别给
.progress加mt-*类,靠gap-2统一控制垂直节奏
小屏下进度条对齐与间距重置
横向转竖排后,gap 从水平变成垂直,不重设会导致步骤间空隙过大、视觉断裂;同时 align-items: center 在竖排时会让文字“悬空”。必须在 @media (max-width: 576px) 里覆盖:
-
.step-nav { gap: 1.5rem; }—— 别用gap-4,它在 flex-column 下行为不一致 -
.nav-link { padding: 0.75rem 1rem; align-items: flex-start; }—— 强制文字左对齐,不随进度条高度浮动 -
.progress { width: 100%; }—— 确保填满可用宽度,不受父级nav-link内联样式影响 - 字体太大撑高?加
font-size: 0.875rem;,防止行高拉伸导致进度条偏移
状态同步时容易忽略的细节
进度条宽度变化 ≠ 步骤状态更新。JS 更新 aria-current 时,必须同步更新对应项的 style.width,否则会出现“UI 显示第 3 步,但进度条还停在 40%”的错位:
- 不要只改
aria-current="step"就完事,得拿到当前项索引,计算累计完成比例:width = (index / totalSteps) * 100 + '%' - 如果某步可跳过(如“邮箱验证”非必填),不能简单按索引算,得用实际已通过的步骤数
- 服务端渲染时,
style="width: XX%"必须由后端输出,否则客户端 hydrate 后首次 render 会闪动 - 别用
transition: width .3s直接加在.progress-bar上——小屏下动画易卡顿,建议用will-change: width或交由 JS 控制帧率
最麻烦的不是写代码,而是每次改布局都要重新校验:小屏下文字是否折行、进度条是否贴底、箭头线是否对齐圆点、键盘焦点是否还在 nav-link 上——这些没法靠一个 class 解决,得一行一行看渲染结果。











