用 display: grid 实现九宫格最稳,grid-template-columns: repeat(3, 1fr) 设三列等宽,配合 gap 控制间距,容器需设明确宽度;小屏用媒体查询降为2列或1列;缺图时用占位元素或 justify-content: center 处理对齐;图片用 object-fit: cover、aspect-ratio: 1/1 和伪元素兜底。

直接用 display: grid 最稳,别碰 float 或 inline-block 拼九宫格——前者响应式崩得快,后者间隙难控,还容易换行错位。
用 grid-template-columns: repeat(3, 1fr) 固定三列等宽
这是最干净的起点。3 列是朋友圈常见布局,1fr 让每列均分容器宽度,不依赖图片原始尺寸。
注意:容器必须有明确宽度(比如 width: 100% 或设为 max-width: 600px),否则 fr 单位无参照,网格会撑满整个视口。
示例:
立即学习“前端免费学习笔记(深入)”;
.grid-photos {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 4px; /* 图片间空隙,别用 margin 模拟 */
}-
gap是唯一推荐的间隔控制方式;用margin会导致最后一行子项右侧多出空白 - 如果要适配小屏,加
@media (max-width: 480px)改成repeat(2, 1fr),再小就1fr - 不要给子项(
img)设固定宽高,用width: 100%; height: 100%; object-fit: cover;保形裁切
处理图片数量不是 3 的倍数时的底部对齐问题
9 张图很完美,但 7 张或 8 张时,最后一行只有 1–2 项,默认左对齐,看起来像缺角——这不是 bug,是 grid 的默认行为。
解决方法只有两个有效选项:
- 加空占位
<div class="placeholder"></div>补满最后一行(共需补3 - (n % 3) || 0个),并用visibility: hidden隐藏,避免影响语义和可访问性 - 改用
justify-content: center让整行居中,但要注意:这会让 1 张图居中、2 张图并排居中,视觉节奏变松散,和朋友圈“左对齐+紧凑”的风格不符 - 不推荐用
grid-column: span 3合并最后一项来填满——它会拉宽单图,破坏统一网格感
图片加载失败或尺寸异常时的兜底样式
用户上传的图可能极窄(如截图)、极高(如长截图),或加载失败显示成浏览器默认的「破损图标」,这时 object-fit: cover 会裁掉关键内容,而纯 contain 又留白太多。
稳妥做法是组合控制:
- 给
img设min-height: 0(防止父 grid item 被图片固有高度撑开) - 用
aspect-ratio: 1 / 1强制正方形容器(现代浏览器支持良好,iOS Safari 16.4+ 已支持) - 加载失败时,用
img::before伪元素 +content显示灰色方块或提示文字,比onerrorJS 更轻量
例如:
.grid-photos img {
width: 100%;
height: 100%;
object-fit: cover;
aspect-ratio: 1 / 1;
min-height: 0;
}
.grid-photos img::before {
content: "⚠";
display: flex;
align-items: center;
justify-content: center;
background: #f0f0f0;
color: #999;
}真正麻烦的是动态加载场景:新图插入后要重算 grid 行数,但 grid 本身不触发重排通知;这时候得靠 JS 监听容器 resize 或用 MutationObserver 检测子节点变化——不是 CSS 能扛住的。


















