直接改$grid-columns不生效,是因为bootstrap 5的列类由make-col-classes()混合宏硬编码生成(默认只到12),需重写该宏并确保在bootstrap原始调用前覆盖,且编译链路、sass版本和类名语义兼容性均需同步处理。

为什么直接改 $grid-columns 不生效
Bootstrap 5 默认用的是 12 列栅格,想改成 24 列,很多人第一反应是覆盖变量 $grid-columns: 24 就完事——但编译后发现 .col-6 还是占一半宽度,.col-12 才占满,根本没按 24 等分。原因在于:Bootstrap 的列类(如 .col-1 到 .col-12)是硬编码生成的,不是靠变量动态推导出来的。
必须重写 make-col-classes() 混合宏
Bootstrap 的列工具类由 SCSS 混合宏 make-col-classes() 生成,默认只循环到 12。要支持 24 列,得自己重定义这个混合宏,并确保它在 Bootstrap 的原始调用前被覆盖。
实操步骤如下:
- 新建自定义 SCSS 文件(比如
_custom-grid.scss),先定义$grid-columns: 24 - 复制 Bootstrap 源码中
make-col-classes()的完整定义(注意:Bootstrap 5.3+ 版本该宏位于scss/mixins/_grid.scss) - 修改内部循环上限为
24(原为12),并确保所有span计算逻辑仍基于$grid-columns - 在导入 Bootstrap 核心文件 之后、调用
@include make-col-classes()之前,插入你重写的混合宏定义
关键代码片段(简化示意):
@mixin make-col-classes($columns: $grid-columns, $breakpoints: $grid-breakpoints, $container-max-widths: $container-max-widths) {
@each $breakpoint, $container-max-width in $container-max-widths {
@include media-breakpoint-up($breakpoint, $breakpoints) {
@for $i from 1 through $columns {
.col#{$breakpoint}-#{$i} {
flex: 0 0 auto;
width: percentage($i / $columns);
}
}
}
}
}
改完后 .col-12 会变成半宽,但旧类名语义失效了
这是最容易忽略的副作用:原来 .col-6 表示“占 6/12 = 50%”,现在 .col-6 变成“占 6/24 = 25%”。如果你项目里已大量使用 .col-4、.col-8 等,它们的视觉效果全变了,而且语义断裂——.col-12 不再是“一半”,而是“一半”只对应 .col-12(因为 12/24=0.5),但开发者直觉上仍会认为它是“十二分之一”。
建议同步做两件事:
- 全局搜索替换旧类名(如把
.col-4改成.col-8),保持视觉比例不变 - 避免混用新旧列数逻辑;不要在同一个项目里既用
.col-6(24 列语义)又依赖它过去代表“半宽”的认知 - 如果只是局部需要更细粒度控制,优先考虑用
flex+flex-grow或 CSS Grid,而非全局改栅格基数
编译时注意 Sass 版本和 Bootstrap 源码路径
Bootstrap 5.3 要求 Dart Sass ≥ 1.33.0,老版本 Node Sass 已不兼容。另外,make-col-classes() 在不同 Bootstrap 小版本中位置和参数略有差异:
- Bootstrap 5.0–5.2:宏在
scss/mixins/_grid.scss,参数为($gutters: $grid-gutters) - Bootstrap 5.3+:宏移到
scss/mixins/_utilities.scss,且默认不自动调用,需显式@include make-col-classes() - 务必检查你用的 Bootstrap npm 包是否含源码(
node_modules/bootstrap/scss/),否则无法覆盖混合宏
最稳妥的做法:用 npm install bootstrap@5.3.3 锁定版本,再对照其 scss/ 目录下的实际文件结构来抄写和修改混合宏。
改列数这事,表面是改个数字,实际是牵动整个栅格类的生成逻辑和团队对类名的理解惯性。别只盯着变量,得盯住混合宏、编译链路和已有代码的兼容成本。











