极简工具箱

免费在线工具 · 本地计算 · 无需上传

Grid 布局入门:fr 单位、repeat 与响应式不用媒体查询

要让卡片「一行放得下就放三个,放不下自动变两个、一个」,Grid 只需要一行 CSS,不用写任何媒体查询。

广告位(百度联盟)

一、先建立行列的概念

.grid {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;   /* 三列:固定 200 + 两个弹性 */
  grid-template-rows: auto 1fr auto;      /* 三行:头、主体、尾 */
  gap: 16px;
}

子元素默认按顺序自动填充格子(行优先)。也可以用 grid-column / grid-row 指定跨格:

.hero { grid-column: 1 / -1; }   /* 从第 1 条网格线到最后一条,即横跨整行 */

二、fr 是「剩余空间的比例」

1fr 不是「一份宽度」,而是「剩余空间的一份」。所以 200px 1fr 1fr 里,先扣掉 200px 和 gap,剩下的再平分给两个 1fr。

和 % 的区别很重要:% 是按容器总宽算,加上 gap 容易溢出;fr 自动扣除 gap,不需要手动计算。

三、一行搞定响应式

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

拆解:

效果是:容器宽 1000px 时放 4 列,缩到 600px 自动变 2 列,手机上 1 列。全程不需要媒体查询。

auto-fit 与 auto-fill 的区别:空间有富余时,auto-fit 会把空轨道折叠、让现有列变宽;auto-fill 保留空轨道,列宽不变。做卡片列表通常用 auto-fit。

四、命名区域:给布局画草图

.page {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 200px 1fr;
}
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

grid-template-areas 就像在代码里画了一张 ASCII 图,改布局只改这张图,可读性远高于算网格线。做移动端时只需重定义一次 areas:

@media (max-width: 640px) {
  .page { grid-template-areas: "header" "main" "sidebar" "footer"; grid-template-columns: 1fr; }
}

五、对齐

六、几个坑

七、Flex 还是 Grid

场景推荐
导航栏、按钮组、标签列表Flex(一维)
整页布局、卡片墙、图片网格Grid(二维)
需要行列同时对齐Grid
元素数量不定、需要自动换行Grid 的 auto-fit

两者都支持 gap,也都能嵌套。实际项目里常见「Grid 搭页面骨架,Flex 排内部元素」。

小结

fr 分的是剩余空间;repeat(auto-fit, minmax(240px,1fr)) 一行实现响应式;grid-template-areas 让布局像画图;1fr 撑破时用 minmax(0,1fr)。

本文相关工具(本地计算,无需上传)

更多使用教程