根本原因是未正确设置 .row 的 flex-wrap 行为或遗漏基础类;.row 默认 wrap 会换行,但误加 flex-nowrap、缺失 .col-* 基础类、或缺少 .container 容器会导致视觉上“不换行”。

为什么 .row 里的 .col 死活不换行?
根本原因不是 CSS 写错了,而是你没关掉 Flex 的自动换行行为。Bootstrap 5 的 .row 默认是 flex-wrap: wrap,它本就会换行——但一旦你手动加了 flex-nowrap、white-space: nowrap,或者用了 .row-cols-* 配合过少的列数,它就真不换了。
常见诱因:
- 误加
flex-nowrap类(比如从旧项目复制代码时带进来的) - 在
.row上写了style="flex-wrap: nowrap"且没覆盖 - 用了
.row-cols-5却只放了 6 个.col—— 它不会“多出一个就换行”,而是把第 6 个硬塞进同一行,导致溢出或横向滚动 - 子
.col内容宽度过大(如未限制图片、表格、长单词),触发了 flex 最小宽度保护(min-width: 0缺失)
.row 不换行的合法配置有哪些?
真要禁用换行,得明确知道代价:所有子列会被强行压在同一行,超出视口就产生水平滚动条,响应式断点类(如 .col-md-6)依然生效,但它们的百分比宽度会在窄屏下被压缩到极小,甚至文字重叠。
可用方式(仅限特定场景,如横向时间轴、标签云、固定设备仪表盘):
- 直接加
flex-nowrap类:<div class="row flex-nowrap">...</div> - 用工具类关闭 gutter 换行副作用:
<div class="row flex-nowrap g-0">(<code>g-0移除默认 1rem 间隙,减少溢出风险) - 配合
overflow-x-auto让容器可滚动:<div class="row flex-nowrap overflow-x-auto"> <li>若需内容截断,给 <code>.col加text-truncate或min-w-0+overflow-hidden -
.row-cols-5单独用 → 每行最多 5 列,自动换行 -
.row-cols-5.flex-nowrap→ 强制单行,列宽仍按 20% 算,但超 100% 就溢出 - 想让 10 列严格单行且等宽?用
.row.flex-nowrap+ 手动设.col为flex: 0 0 calc(10% - var(--bs-gutter-x) * 9 / 10)(不推荐,维护成本高) - 有没有至少写一个
.col-*(如.col-12、.col)?没有就补上 - 是否误删了
.container?没容器,.row的负 margin 会让列左移出屏幕,看起来像“缩成一行” - 是否在
.col里嵌套了未包裹.row的新列?嵌套错位会导致父列高度塌陷,视觉上像“没分行”
.row-cols-* 和换行行为的关系
.row-cols-5 这类类名**不控制是否换行,只控制每行最多显示几个等宽列**。它底层是 flex: 0 0 20% + flex-wrap: wrap,所以它默认仍会换行——只是“每行最多 5 个”,第 6 个自动掉到下一行。
但如果你同时加了 flex-nowrap,那 .row-cols-5 就失效了:它还是试图让每个 .col 占 20%,但所有列被锁死在一行,总宽变成 120%、140%……最终溢出。
关键区别:
移动端下 .row 看似不换行的真正原因
手机上列“挤成一行”往往不是 .row 不换行,而是你漏写了 .col- 基础类。Bootstrap 5 移动优先,.col-md-4 在 xs/sm 屏下完全无效,浏览器按普通块级元素渲染,但又没给 width,结果就是内容靠自身长度撑开,视觉上像“没换行”,其实是列宽失控。
检查这三点:
最易被忽略的是 .container 缺失和基础断点类遗漏——这两处一错,整个栅格逻辑就从根上失效,后续调任何 .row 配置都救不回来。











