CSS 中 repeat(var(--n), 1fr) 不被支持,因 repeat() 首参仅接受字面量数字或 auto-fit/auto-fill;变量需用于整个轨道定义如 --cols: 1fr 1fr,再 grid-template-columns: var(--cols)。

repeat(var(--n), 1fr) 根本不被解析
这不是写法问题,是 CSS 规范层面的硬限制:repeat() 的第一个参数只接受字面量数字(如 3)或 auto-fit/auto-fill,var(--n) 在这里会被浏览器当作无效值直接丢弃。整条 grid-template-columns 声明会静默失效——Computed 面板里该属性为空,开发者工具中显示为 strikethrough,但无任何错误提示。
常见错误现象包括:
-
--n: "3"(带引号字符串)→ 解析失败 -
--n: 3px或--n: 3.0(带单位或小数)→ 同样被拒 - 变量定义在
:root,但网格容器是.grid且未重声明 → 作用域不匹配,变量不可见
grid-template-columns 支持 var(),但仅限“轨道定义”上下文
var(--cols) 能用,但前提是它本身就是一个合法的轨道列表字符串,比如 --cols: 1fr 1fr 1fr,然后写成 grid-template-columns: var(--cols)。这和 repeat(var(--n), 1fr) 是两回事:前者是变量替换整个值,后者是试图让函数内部解析变量——后者永远不行。
关键约束:
立即学习“前端免费学习笔记(深入)”;
-
--cols必须定义在目标选择器内(如.grid { --cols: 1fr 1fr; }),不能只靠:root继承 - 内联方式最可靠:
<div class="grid" style="--cols: 1fr 1fr 1fr"> - JS 动态修改时,必须调用
el.style.setProperty('--cols', '1fr 1fr 1fr'),而不是改:root
IE11 和旧版 Safari 的兼容性断层
var() 在 grid-template-columns 中完全不被 IE11 支持;Safari 14.1 之前也不支持 gap: var(--g),只认拆开的 grid-row-gap 和 grid-column-gap。这意味着你写的动态列数方案,在这些浏览器里会直接退化为单列或无样式。
降级必须主动做:
- 用
@supports (display: grid) and (grid-template-columns: repeat(2, 1fr))包裹现代写法 - fallback 方案建议用
display: flex+flex-wrap,而非寄希望于变量兜底 -
--g: 16px✅,但--g: 16❌(Safari 会忽略无单位值)
真正可控的动态列数只有两种路径
一种是放弃“固定 N 列”,改用弹性方案:repeat(auto-fit, minmax(280px, 1fr)) —— 它不依赖变量,靠浏览器自动算列数,且能响应内容宽度变化;另一种是 JS 真实写入:el.style.gridTemplateColumns = `repeat(${n}, 1fr)`。
容易被忽略的细节:
- JS 修改后若布局没更新,先检查是否触发了重排(比如改完后读取
offsetHeight) - 子网格要隔离变量名,比如父级用
--cols,子级用--sub-cols,否则会互相覆盖 -
grid-template-areas完全不支持变量插值,所谓“动态区域”只能靠媒体查询整套重写


















