1fr 1fr不等宽是因为浏览器先扣除gap、固定尺寸等内容占用的确定空间,再将剩余空间按比例分配;min-width、混用单位、未设min-width:0、嵌套grid父容器限制及ie11不支持fr等均会导致偏差。

fr单位不能直接实现“视觉等分”,它只对扣除固定占用后的剩余空间做比例分配;写1fr 1fr看起来等宽,但内容撑开、gap、minmax()或父容器限制都可能让结果偏离预期。
为什么1fr 1fr有时根本不等宽?
浏览器不是把容器宽度直接砍成两半,而是先扣掉所有确定尺寸,再分剩下的。常见干扰项包括:
-
gap: 1rem会从总宽中扣除(比如两列时扣掉1次gap,三列扣2次) - 某列里放了
min-width: 300px的卡片,而容器总宽才520px → 剩余空间只剩220px,两列1fr各得110px,远小于内容所需 - 混用了
%或px:比如200px 1fr 1fr,后两列分的是“总宽 − 200px”,不是总宽 - 子元素没设
min-width: 0,长文本或图片强行撑开网格项,导致fr可分配空间被压缩
repeat() + 1fr比手写1fr 1fr 1fr更可靠
重复写多个1fr不仅冗余,还容易漏改。用repeat()语义清晰且便于维护:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
但注意:repeat(3, 1fr)仍是固定列数,小屏下会挤压。真要响应式,得升级为:
.grid {
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)));
}
这行代码的意思是:“每列至少300px,最多占满它该得的那份剩余空间;能放几列放几列,空轨道自动合并”。
嵌套Grid里1fr为啥不占满父项?
外层1fr的宽度不会透传给内层Grid。内层1fr只认自己**直接父容器的可用宽度**,而这个父容器往往:
- 没设
width: 100%或min-width: 0,被内部长文本撑宽,导致内层Grid可分配空间变小 - 默认
width: auto,不是继承外层比例 —— 必须显式加width: 100%,再定义自己的grid-template-columns - 如果父项是Flex子项,还要检查
flex-basis是否限制了宽度计算依据
IE11和旧Safari用户看到的是空白或堆叠?
IE10/11完全不识别fr,遇到含fr的grid-template-columns整条声明会被忽略,退化为块级流。不能只靠@supports (display: grid)检测,因为IE支持display: grid但不支持fr。降级方案必须明确:
@supports not (grid-template-columns: 1fr) {
.grid { display: flex; flex-wrap: wrap; }
.grid > * { flex: 1 1 300px; } /* 模拟minmax(300px, 1fr) */
}
真正难的不是写出1fr 1fr,而是意识到:fr不是比例尺,它是剩余空间的切分器;只要有一处固定尺寸、内容溢出或父级约束没理清,它就立刻失准。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











