垂直选项卡需用d-flex包裹nav与tab-content为兄弟节点,nav加flex-column和显式宽度,tab-content设flex-grow-1,移动端用d-none d-md-flex,JS切换须用bootstrap.Tab.getInstance().show()确保状态同步。
垂直选项卡必须用 d-flex 外层包裹,不能嵌套 tab-content
直接把 tab-content 放进 nav 里,会导致内容区塌陷、不随导航等高、响应式错乱。bootstrap 的 tab 插件依赖同级结构才能正确计算尺寸和触发切换。
-
nav和tab-content必须是兄弟节点,共同包裹在div class="d-flex"内 - 移动端默认不启用垂直布局,加
d-none d-md-flex到外层容器,避免小屏上文字挤成一列 - 别给
nav设height或overflow,它应由内容自然撑开;否则 tab 切换时可能高度抖动
nav-tabs 加 flex-column 不够,必须配显式宽度
Bootstrap 5 的 .nav-tabs 类内部强制设了 flex-direction: row,仅加 flex-column 会失效——它被 CSS 优先级更高的规则覆盖。真正起效的是组合写法,且宽度不可省略。
- 写成
class="nav flex-column nav-tabs",顺序无关,但两个类都得有 - 必须设
style="width: 12rem"或用工具类如mw-150,否则nav收缩到最小内容宽,文字换行、点击区域偏移 -
nav-link要加text-center和w-100,不然左对齐文字会超出容器或触发意外折行 - 删掉默认的
margin-bottom: -1px(它只适用于横向),改用mb-2控制纵向间距
JS 切换时 active 类不同步?别手动操作 DOM
用 bootstrap.Tab.getInstance(el).show() 或模拟点击(document.querySelector('[href="#profile"]').click())才能保证 active 类真实更新。手写 classList.add('active') 很容易漏掉旧项的移除,导致多个 tab 同时高亮。
- 动态渲染后(比如 AJAX 加载 tab 内容),先调用
bootstrap.Tab.getOrCreateInstance再.show() - 监听
shown.bs.tab事件时,检查e.target是否为当前nav-link,而不是靠data-bs-target字符串匹配 - 如果用了自定义路由或 hash 变化触发 tab 切换,务必在
hashchange回调里显式调用.show(),否则视觉与状态脱节
右侧垂直选项卡只需交换 DOM 顺序,不用改 CSS
想让选项卡靠右,不是加 justify-content-end 或 ms-auto,而是把 nav 放到 tab-content 后面,再用 flex-row-reverse —— 这样既保持语义,又避免负 margin 干扰布局流。
- 结构写成:
<div class="d-flex flex-row-reverse"> <div class="tab-content flex-grow-1">...</div> <nav class="nav flex-column nav-tabs" style="width: 12rem">...</nav> </div> - 不要对
nav单独设margin-left,它会破坏 flex 布局的自动对齐逻辑 - 右侧布局下,
tab-content仍需flex-grow-1,否则宽度无法填满剩余空间
aria-controls 和 aria-labelledby)必须随 DOM 位置同步更新,否则屏幕阅读器会读错关联关系。这不是样式问题,但一旦上线就很难被发现。











