推荐用 css 变量而非硬编码 style.gridtemplatecolumns,因其避免字符串拼接错误、解耦布局逻辑、支持媒体查询覆盖与 transition 动画、减少强制同步布局;需确保变量作用域匹配选择器,并配合 minmax() 或约束样式提升健壮性。

直接改 --columnsCount 变量就行,不用碰 gridTemplateColumns 字符串拼接,也别在 JS 里反复 setStyle。
为什么推荐用 CSS 变量而不是直接改 style.gridTemplateColumns
硬编码字符串拼接(比如 gridContainer.style.gridTemplateColumns = `repeat(${n}, 1fr)`)看似直白,但容易漏掉单位、引号嵌套、模板转义问题;更重要的是,它把布局逻辑耦合进 JS,后续维护、媒体查询覆盖、动画过渡都会变麻烦。CSS 变量天然支持级联、继承和媒体查询重写,JS 只需负责“通知”,样式层自己响应。
- 变量可被
@media覆盖,比如小屏强制--columnsCount: 1,大屏再设为4 - 支持 CSS 过渡:给
grid-template-columns加transition,变量变化时列宽会平滑缩放(注意仅限轨道尺寸变化,新增/删除项不触发过渡) - 避免 JS 频繁操作 DOM 样式属性,减少强制同步布局(layout thrashing)
setProperty 的调用时机和选择器范围要对
必须确保 JS 修改的变量作用域能被目标元素捕获。常见错误是:变量定义在 :root,但网格容器用的是局部 class 选择器,结果没生效。
- 如果网格容器是
.gridBox,变量应在该选择器内定义:.gridBox { --columnsCount: 3; grid-template-columns: repeat(var(--columnsCount), 1fr); } - 调用时选中该容器:
const gridBox = document.querySelector('.gridBox');,再gridBox.style.setProperty('--columnsCount', '4') - 不要写成
document.documentElement.style.setProperty——除非你真把变量挂到了:root,且所有网格都依赖它
动态列数搭配 minmax() 更健壮
纯 repeat(var(--columnsCount), 1fr) 在窄屏下容易把列压得过小,尤其当列数固定为 4 但容器只有 300px 宽时,每列只剩 75px,内容挤成一团。
- 换成
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr))),就不再需要 JS 控制列数——浏览器自动算 - 但如果后端或配置要求「必须精确控制列数」(比如报表固定 3 列),那就得坚持用变量 +
repeat(var(--columnsCount), 1fr),并配合max-width和overflow-x: hidden防溢出 - 注意:IE11 不支持
var()在grid-template-columns中,如需兼容,得用@supports (display: grid)包裹,再 fallback 到 Flexbox
resize 监听不是万能的,ResizeObserver 更准
监听 window.resize 改列数,常遇到两个问题:一是窗口拖拽时触发太频繁,二是容器本身尺寸变化(比如侧边栏展开)却不会触发 resize。
- 用
ResizeObserver观察网格容器自身尺寸:new ResizeObserver(() => { updateColumnsByWidth(gridBox); }).observe(gridBox); -
updateColumnsByWidth函数里根据gridBox.clientWidth算当前应显示几列,再setProperty - 比
resize更精准,且不依赖窗口全局事件,适合嵌入式组件或微前端场景
真正难的不是改变量,而是让列数变化时内容不跳、不闪、不撑破父容器——这取决于你是否提前约束了 gap 单位、是否加了 box-sizing: border-box、以及有没有处理好子项的 max-width 和文本换行。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











