repeat(auto-fit, minmax()) 是唯一靠谱组合,因 auto-fit 收空轨道、minmax() 的最小宽控列数,需配 viewport 元标签、合理 gap 和父容器约束,图片须套带 aspect-ratio 的容器并设 max-width: 100%。

直接用 repeat(auto-fit, minmax()) 就能实现,但必须写对参数、配对容器约束,否则小屏照样溢出或列数不减。
为什么 auto-fit + minmax() 是唯一靠谱组合
浏览器在渲染时会不断尝试往容器里塞新列,直到“当前列最小宽 + gap”超出剩余空间。所以真正控制列数的是 minmax() 的第一个参数(最小宽度),而 auto-fit 负责把塞不下的空轨道收掉,把空间匀给有内容的列。
-
auto-fill会保留所有可能轨道,窄屏下出现空白列或卡片被压扁——常见于复制代码时手误 -
minmax(200px, 1fr)在视口 400px 宽时仍可能撑出两列(200×2 + gap),实际最小临界宽度是列数 × 最小宽 + gap × (列数 − 1) - 若图片项里有固定宽元素(如
<img style="max-width:90%">),Grid 弹性逻辑直接失效,必须改用max-width: 100%+height: auto
minmax() 第一个参数不能写死像素值
写成 minmax(150px, 1fr) 看似合理,但小屏下它仍允许两列并存,只是每列窄到 150px —— 图片被压缩、文字折行、布局跳动全来了。要让列数随屏幕变窄自动减少,得让这个“最小值”本身具备响应性。
- 推荐写法:
minmax(max(150px, 34%), 1fr):宽屏时 34% 150px,Grid 被迫抬高门槛,放弃第三列 - 百分比不是 magic number,
33.4%~36%都可试,gap 越大,百分比建议略调高(gap: 40px → 用 38%) - 别用
min(150px, 50%):小屏下 50% 值变小,反而鼓励多列,完全背离目标
图片项必须套一层容器,且设 aspect-ratio
直接把 <img> 放进 Grid 容器,在 Safari 和部分 Android WebView 中会忽略 object-fit 或缩放异常。更关键的是,没 aspect-ratio 的容器,图片加载前高度为 0,导致布局跳动(CLS)。
- 每张图必须包裹在
<div class="img-wrapper"> 里,该容器设 <code>aspect-ratio: 4/3(按你图源比例调整) -
<img>设width: 100%; height: 100%; object-fit: cover;,确保填满不拉伸 - 加
loading="lazy",但首屏图显式写loading="eager",否则 LCP 拖慢 -
srcset和sizes必须匹配真实容器宽度,比如 grid 列宽 ≈ 视口 90%,sizes就得写"90vw",不能笼统写"100vw" - 缺
<meta name="viewport" content="width=device-width, initial-scale=1">:浏览器按桌面视口渲染,Grid 容器宽度算错,响应逻辑从第一步就崩了 -
gap过大(如gap: 40px):窄屏下光间距就吃掉大半宽度,Grid 提前判定“塞不下”,列数锐减,但你却以为是代码问题 - 父容器没设
max-width或width:Grid 计算基于其直接父容器宽度,如果父容器是body且没约束,它就按 viewport 全宽算,和你预期不符
容易被忽略的硬性前提
再完美的 repeat(auto-fit, minmax()) 也会在三个地方当场失效:











