fr是剩余可用空间的份数,仅在扣除显式尺寸(如px、%)后的空间中按比例分配,不直接作用于容器总宽;需配合min-width:0、max-width:100%等控制内容以避免撑开失效。

fr单位到底怎么分配剩余空间
fr不是固定像素,也不是百分比,它是“剩余可用空间的份数”。比如 grid-template-columns: 1fr 2fr 1fr,容器总剩余空间被切成4份,中间列占2份(50%),两边各占1份(25%)。关键点在于:fr只在**已扣除显式尺寸后的剩余空间**上计算——如果有带px或%的列,fr会忽略它们占用的部分再均分剩下的。
常见误解是认为fr直接按比例切整个容器宽度,实际它和auto、minmax()、固定宽列共存时行为更复杂。例如:grid-template-columns: 200px 1fr 2fr,先扣掉200px,剩下空间才按1:2分给后两列。
三栏布局中左右固定、中间自适应的写法
这是最常用也最容易出错的场景。不能只写1fr 2fr 1fr——那三栏都会随内容伸缩。要让左右栏“钉住”,中间栏吃掉所有剩余空间:
container {
display: grid;
grid-template-columns: 250px 1fr 250px;
}
这样左栏250px、右栏250px、中间栏自动填满中间空隙。如果希望左右栏最小250px、但能随窗口变大而略撑开,改用minmax(250px, max-content);若想左右栏始终刚好包裹内容、中间撑满,则用max-content 1fr max-content,但要注意max-content可能引发换行或溢出。
- 避免混用
fr和%:比如20% 1fr 20%,%按容器宽算,fr按剩余空间算,结果不可预测 - 移动端适配时,用
@media把三栏改成1fr单列,别依赖fr自动响应 -
fr不支持负数,也不能写0fr——想隐藏一栏请用display: none或grid-column: span 0
内容撑开导致fr失效的典型表现
当某栏内容(尤其图片、长单词、flex容器)没设约束时,Grid默认按min-width: auto处理,可能强行扩大该列,挤压其他fr列。浏览器会优先满足内容最小宽度,fr退居次位。
解决方法不是调大fr数值,而是控制内容自身:
- 给图文容器加
min-width: 0(触发新的BFC,允许收缩) - 图片加
max-width: 100%; height: auto - 长文本加
overflow-wrap: break-word - 避免在grid item里嵌套
display: flex且未设flex-shrink: 1
验证是否生效:打开开发者工具,看该列的computed width是否仍大于预期——如果是,问题一定出在内容层,而非grid定义。
IE11兼容性下fr单位的替代方案
IE11完全不支持fr单位,用grid-template-columns: 1fr 2fr 1fr会直接失效(整行回退为block流)。如需兼容,必须放弃Grid或用JavaScript降级。
纯CSS折中方案只有两个:
- 改用
display: table+table-layout: fixed,但丧失响应性和语义 - 用
float+calc()模拟,例如width: calc((100% - 500px) / 2),但维护成本高且易出精度误差
现实项目中,如果目标用户仍有显著IE11流量,建议用@supports (display: grid)做特性检测,对不支持的环境加载独立布局CSS——别指望fr能在IE里“差不多工作”。
fr单位本身很干净,但它的干净建立在“内容可控”和“浏览器支持明确”的前提上。真正卡住人的往往不是grid语法,而是那一行没加min-width: 0的div,或者那个忘了设max-width的img标签。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











