纯 css 无法用变量控制 repeat() 的列数,因 repeat() 首参必须为字面量整数,css 变量仅字符串替换、不参与求值,故 repeat(var(--cols), 1fr) 被静默丢弃;可靠方案是 js 协同或改用 auto-fit + minmax()。

纯 CSS 无法用变量控制 repeat() 的列数——这不是写法或兼容性问题,是浏览器解析层的硬性限制:第一个参数必须是字面量整数,repeat(var(--cols), 1fr) 会被静默丢弃,Computed 面板中该属性为空,且无任何报错提示。
为什么 repeat(var(--cols), 1fr) 总是不生效
CSS 变量只做字符串替换,不参与表达式求值。repeat() 在语法层面就拒绝非字面量数字作为首参。即使 --cols: 3 已定义,repeat(var(--cols), 1fr) 在所有现代浏览器(Chrome/Firefox/Safari/Edge)中全部失效。
-
--cols: "3"(带引号)、--cols: 3px(带单位)、--cols: 3.0(小数)全都不行 -
calc()、attr()、env()、@property同样不被支持 - DevTools 里能看到该规则被划掉(strikethrough),但控制台不会报错
哪些 Grid 参数能安全用变量控制
变量可合法用于以下位置,只要类型匹配且单位正确:
-
gap:推荐拆成row-gap: var(--row-gap)和column-gap: var(--col-gap),避免 Safari 14.1 之前不兼容gap: var(--g) -
minmax()内部:minmax(var(--min-width), 1fr)有效,但--min-width: 250px必须带单位;慎用em/rem,字体缩放可能意外触发换行 -
grid-auto-rows:grid-auto-rows: minmax(var(--row-height), auto)可行 -
calc()表达式:width: calc(var(--gap) * 2)是安全的
真正动态改列数的可靠方案:JS + CSS 变量协同
必须靠 JS 读取变量后显式设置内联样式,或通过 setProperty() 触发 CSS 层响应。关键不是“怎么写”,而是“在哪写、谁来读”:
- 变量作用域必须对齐:如果网格容器是
.grid,就在.grid { --cols: 3; }中定义,而不是只挂在:root - JS 修改时操作具体元素:
el.style.setProperty('--cols', '5'),不是document.documentElement.style.setProperty - 读值要清洗:
parseInt(getComputedStyle(el).getPropertyValue('--cols').trim()),否则可能得NaN - 写入后若需立即重排(如 resize 后强制计算),可读一次
el.offsetHeight - 高频更新场景(如滚动)必须防抖;推荐监听
storage或自定义事件触发更新
更轻量、免 JS 的替代思路:用 auto-fit + minmax()
如果你要的是“容器变窄时自动减少列数”,而不是“必须等于某个变量值”,那完全不用 JS:
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)));
这行代码让浏览器根据容器宽度和最小项宽(280px)自动决定列数,视觉上更紧,且天然响应式。它不依赖任何变量,也不需要 JS 干预,是多数场景下更健壮的选择。
真正容易被忽略的点是:所谓“动态列数”,绝大多数时候其实是内容驱动的响应行为,而非指令驱动的精确控制;强行用 JS 去“设列数”,反而会破坏 minmax() 和媒体查询的弹性逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











