Bootstrap原生无steps组件,需用nav+aria-current+响应式栅格构建垂直步骤引导:语义化nav包裹ul.nav.flex-column,每步为li.nav-item内含a.nav-link,状态靠aria-current="step"驱动,响应式通过flex-column flex-md-row叠加实现,JS切换须同步更新aria-current属性。
bootstrap 原生不提供 steps 组件,但用 nav + aria-current + 响应式栅格组合,能做出真正可用的垂直步骤引导——关键不是“让水平步骤变垂直”,而是从结构上按垂直流组织,再用断点控制堆叠与展开。
用 nav + flex-column 实现基础垂直步骤条
别套 .list-group 或硬改 .nav-tabs,它们语义错位、小屏易崩。直接用语义清晰的 nav 包裹 ul,每个步骤为一个 li.nav-item,内部用 a.nav-link 承载标题和状态。
-
ul必须加class="nav flex-column"(不是只加flex-column到父容器) - 每个
nav-link要带href和data-bs-toggle="tab"(若需 JS 切换),否则 Bootstrap 的 tab 插件不识别 - 状态靠
aria-current="step"驱动,不是class="active";CSS 写[aria-current="step"] { font-weight: 600; } - 禁用未激活项时,用
tabindex="-1"+pointer-events: none,而非.disabled(后者会破坏键盘导航)
响应式切换:小屏垂直 → 中屏水平
Bootstrap 没有 .nav-vertical-md 这类类名。.nav.flex-column 是静态方向,无法随断点自动切回水平。真响应式得靠工具类叠加:
- 写成
class="nav flex-column flex-md-row",注意顺序:flex-md-row必须在flex-column后面,否则被覆盖 - 大屏下箭头线用
::after画,但只对非末项生效:.nav-item:not(:last-child) .nav-link::after - 小屏堆叠时重置间距:
@media (max-width: 576px) { .nav.flex-column { gap: 1rem; } },别依赖gap-3这类响应式工具类,它在flex-column下行为不稳定 - 字体大小建议小屏设为
0.875rem,避免nav-link高度撑开导致行距失衡
垂直布局下内容区对齐与宽度控制
垂直步骤条常配侧边栏,内容区容易错位或溢出。重点不是调 width,而是用 Bootstrap 栅格天然约束:
- 把步骤导航放进
<div class="col-md-3">,内容区放 <code><div class="col-md-9">,不用任何自定义 width <li>若导航项文字过长,给 <code>.nav-link加text-truncate+title属性防撑破容器 - 需要等宽导航项?给每个
.nav-link加flex-grow-1,但前提是父ul有明确最小宽度(如min-width: 180px),否则窄屏下会压缩变形 - 别用
text-center控制居中——它只居中文本,不控制导航容器宽度;该用mx-auto或嵌套在col里 - 优先用原生点击模拟:
document.querySelector('[href="#step2"]').click(),它会自动处理属性同步 - 若必须用 API,记得显式设置:
bootstrap.Tab.getInstance(el).show(); el.setAttribute('aria-current', 'step'); - 动态渲染场景(如 Vue/React)下,DOM 更新可能滞后,切换后要检查
.nav-link[aria-current="step"]是否真实存在,不能只查 class - 服务端渲染时,确保初始 HTML 就输出正确的
aria-current,避免客户端 hydrate 错乱
JS 切换时 aria-current 不同步的坑
这是最隐蔽的问题:手动触发 new bootstrap.Tab().show() 或点击 nav-link 后,视觉激活了,但 aria-current 属性没更新,屏幕阅读器读不出当前步,且 CSS 状态失效。
垂直步骤引导最难的不是样式,是状态与 DOM 的严格同步——aria-current 必须真实反映当前步,否则对可访问性、自动化测试、甚至部分浏览器的 focus 管理都会出问题。别图省事只改 class。


















