fr单位指剩余空间的份数,非百分比;需先扣除px、%等固定宽度,再将剩余空间按份数分配;无剩余空间时fr失效,混用%与fr时顺序影响结果。

fr单位不是“百分比”,而是“剩余空间的份数”
很多人一看到 1fr 2fr 就下意识理解成“第一列占33%,第二列占67%”,这在**容器宽度固定且没有其他固定列**时碰巧对了,但本质错误。fr 的真实含义是:在扣除所有非弹性轨道(如 px、%、auto)占用的空间后,把剩下的可用宽度按份数切分。
-
grid-template-columns: 200px 1fr 2fr→ 先扣掉 200px,剩下空间分成 3 份,1fr拿 1 份,2fr拿 2 份 -
grid-template-columns: 50% 1fr→ 先按容器宽算出 50%,再把剩下那 50% 全给1fr(不是“再分一半”) - 全写
1fr 1fr 1fr时,因为没固定列,剩余空间 = 容器总宽,所以三列真等宽
fr失效的三大典型场景
fr 不是万能胶,它依赖“有剩余空间可分”。以下情况它会退化或表现异常:
- 容器本身宽度不明确:比如父元素是
display: inline-grid或未设width/max-width的div,此时 fr 会回退到min-content,列可能窄得看不见 - 所有列都是固定单位:
grid-template-columns: 200px 300px→ 没有剩余空间,fr 完全不生效 - 嵌套 Grid 中子容器高度为
auto:1fr行高会塌缩成内容高度,必须给子 Grid 显式设height: 100%才能继承父容器高度再计算剩余空间
混用 % 和 fr 时顺序决定结果
百分比列先按容器总宽计算,fr 列后分“剩下的全部”,而不是“剩下的百分比”。顺序一换,布局就变:
.container {
width: 900px;
}
/* 第一列 30% = 270px,剩余 630px → 两个 1fr 各得 315px */
grid-template-columns: 30% 1fr 1fr;
/ 第一列 1fr 先拿走“剩余空间”的 1 份,但此时还没扣百分比 → 实际先算中间 30% = 270px,再把 630px 分给前后两列 → 各 315px,中间最窄 /
grid-template-columns: 1fr 30% 1fr;
结论:% 建议放开头或结尾;中间插 % 会让后续 fr 可用空间难预估,容易踩坑。
立即学习“前端免费学习笔记(深入)”;
真正健壮的响应式分栏:用 minmax() + auto-fit
纯 1fr 在小屏下可能让列窄到文字溢出,全靠媒体查询太累。推荐组合:
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr))));
-
minmax(250px, 1fr):每列至少 250px,最多拿 1 份剩余空间 -
auto-fit:浏览器自动计算能塞几列,不够就换行,不留空隙 - 不需要写死列数,也不用
@media,一行代码搞定流式栅格
fr 的核心从来不是“多酷”,而是“你告诉它怎么分剩余空间”,而剩余空间是否真实存在、是否被正确继承,才是实际项目里卡住人的地方。










