CSS grid-template-rows 属性(千字长文)

什么是 CSS grid-template-rows 属性?

在现代网页布局中,CSS Grid 布局已经成为了构建复杂界面的首选工具。而 grid-template-rows 属性,正是控制网格容器中行高分布的核心配置之一。想象一下你正在设计一张表格,每一行的高度需要根据内容自动调整,或者你希望某些行特别高、某些行特别矮,这时 grid-template-rows 就派上用场了。

这个属性定义了网格容器中每一行的大小,你可以用像素(px)、百分比(%)、视口单位(vh/vw)甚至 fr 单位来设置。它和 grid-template-columns 一起,构成了 Grid 布局的“骨架”。

举个例子:如果你有一个三行的布局,每行高度都是 100px,那么你可以这样写:

.container {
  display: grid;
  grid-template-rows: 100px 100px 100px; /* 每一行都是 100 像素高 */
}

这个属性不只适用于固定值,还能处理更灵活的情况,比如让某一行“撑满剩余空间”——这正是 fr 单位的强项。理解它,你就掌握了控制网格纵向结构的关键。


理解 grid-template-rows 的基本语法

grid-template-rows 的语法结构非常清晰,它接受一个由空格分隔的值列表,每个值代表一行的高度。这些值可以是:

  • 固定长度(如 100px
  • 百分比(如 50%
  • 视口单位(如 20vh
  • fr 单位(表示“分数”空间)
  • auto(自动调整高度)

我们来看一个简单的例子:

.grid-container {
  display: grid;
  grid-template-rows: 1fr 2fr 1fr; /* 第一行占 1/4 空间,第二行占 1/2,第三行占 1/4 */
}

在这个例子中,fr 是“fraction”的缩写,表示“分数单位”。整个可用空间被分成 4 份(1 + 2 + 1),第一行拿走 1 份,第二行拿走 2 份,第三行拿走 1 份。这种分配方式非常灵活,尤其适合内容高度不一的布局。

再看一个使用 auto 的场景:

.grid-container {
  display: grid;
  grid-template-rows: auto 100px auto; /* 第一行和第三行根据内容自动伸缩,第二行固定 100px */
}

这里 auto 的作用是:让行高根据内容自动调整,如果内容较少,行就短;内容多,行就长。它就像一个“弹性弹簧”,能自动适应内容。


使用 fr 单位实现响应式布局

fr 单位是 grid-template-rows 中最具价值的功能之一。它让你能轻松实现响应式布局,让页面在不同屏幕尺寸下依然保持美观。

假设你有一个博客页面,顶部是标题栏,中间是文章内容,底部是页脚。你希望标题栏占 1/4 高度,内容区占 2/4,页脚占 1/4。这时就可以这样写:

.blog-layout {
  display: grid;
  height: 100vh; /* 全屏高度 */
  grid-template-rows: 1fr 2fr 1fr; /* 分成 4 份,按比例分配 */
}

.header {
  background-color: #f0f0f0;
  padding: 20px;
  text-align: center;
}

.content {
  background-color: #ffffff;
  padding: 20px;
}

.footer {
  background-color: #e0e0e0;
  padding: 15px;
  text-align: center;
}

在浏览器中打开这个页面,你会发现无论屏幕多大或多小,三块区域都会按比例缩放。这就是 fr 单位的魅力——它不依赖具体像素,而是基于可用空间的比例进行分配。

💡 小贴士:fr 单位不能单独使用在 grid-template-rows 之外,它必须与其他 fr 或固定单位一起使用,否则会失效。


多种值组合:混合使用不同单位

grid-template-rows 的强大之处在于它支持混合单位。你可以在一个布局中同时使用 px%frauto,让布局更灵活。

比如,你有一个侧边栏导航,固定宽度,主内容区自动伸缩:

.layout {
  display: grid;
  height: 100vh;
  /* 左侧固定 250px,右侧自适应,占剩余空间 */
  grid-template-rows: 100px 1fr;
  grid-template-columns: 250px 1fr;
}

.header {
  background-color: #333;
  color: white;
  padding: 15px;
  text-align: center;
}

.main-content {
  background-color: #f9f9f9;
  padding: 20px;
  overflow: auto;
}

在这个例子中,grid-template-rows 设置了两行:第一行是固定 100px(比如页头),第二行是 1fr,表示“占据剩余高度”。这样,即使你滚动页面,内容区也能自动撑满整个可用空间。

你也可以这样写:

.container {
  display: grid;
  grid-template-rows: 100px 20% 1fr auto; /* 四行:固定 100px、占 20%、占剩余空间、根据内容自适应 */
}

这种写法在构建复杂后台管理系统时非常实用,比如顶部导航栏、侧边菜单、主内容区、底部信息栏等。


与 grid-template-columns 配合使用

grid-template-rows 通常与 grid-template-columns 一起使用,共同定义网格的“行列结构”。它们就像一张棋盘的横纵坐标。

下面是一个完整的案例:创建一个包含头像、姓名、简介和按钮的卡片布局:

<div class="profile-card">
  <img src="avatar.jpg" alt="用户头像" class="avatar">
  <h2 class="name">张三</h2>
  <p class="bio">前端工程师,热爱开源技术。</p>
  <button class="btn">关注</button>
</div>
.profile-card {
  display: grid;
  grid-template-columns: 60px 1fr; /* 第一列 60px(头像),第二列占剩余空间 */
  grid-template-rows: 60px 1fr 40px; /* 第一行 60px(头像区域),第二行占剩余空间(姓名+简介),第三行 40px(按钮区) */
  gap: 10px;
  padding: 20px;
  border: 1px solid #ddd;
  border-radius: 8px;
  width: 300px;
}

.avatar {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  object-fit: cover;
}

.name {
  font-size: 18px;
  font-weight: bold;
  margin: 0;
}

.bio {
  margin: 0;
  font-size: 14px;
  color: #666;
}

.btn {
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

在这个布局中:

  • grid-template-rows: 60px 1fr 40px 表示:

    • 第一行:头像区域,固定 60px 高
    • 第二行:姓名和简介,自动占满剩余空间
    • 第三行:按钮,固定 40px 高
  • grid-template-columns: 60px 1fr 表示:

    • 第一列:头像,固定 60px 宽
    • 第二列:姓名、简介、按钮,占剩余宽度

通过这种方式,你能轻松实现一个对齐精准、响应式良好的卡片组件。


实际应用:构建响应式仪表盘

在实际项目中,grid-template-rows 常用于构建仪表盘、控制面板等复杂布局。下面我们来模拟一个简单的数据看板:

<div class="dashboard">
  <div class="card">销售额:¥120,000</div>
  <div class="card">订单数:892</div>
  <div class="card">用户增长:+15%</div>
  <div class="card">访问量:12,345</div>
  <div class="card">活跃用户:4,567</div>
  <div class="card">系统状态:正常</div>
</div>
.dashboard {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 三列等宽 */
  grid-template-rows: auto 1fr auto; /* 第一行:标题区,第二行:主内容区,第三行:底部状态 */
  gap: 15px;
  padding: 20px;
  height: 100vh;
}

.card {
  background-color: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.card:nth-child(1) {
  grid-row: 1 / 2; /* 第一行 */
}

.card:nth-child(2) {
  grid-row: 1 / 2; /* 第一行 */
}

.card:nth-child(3) {
  grid-row: 1 / 2; /* 第一行 */
}

.card:nth-child(4) {
  grid-row: 2 / 3; /* 第二行 */
}

.card:nth-child(5) {
  grid-row: 2 / 3; /* 第二行 */
}

.card:nth-child(6) {
  grid-row: 3 / 4; /* 第三行 */
}

在这个案例中,grid-template-rows: auto 1fr auto 实现了分层布局:

  • 第一行(auto):放置三个关键指标卡片,高度由内容决定
  • 第二行(1fr):主数据展示区,自动撑满剩余空间
  • 第三行(auto):系统状态栏,高度自适应

这种结构清晰、易于维护,非常适合中后台系统的开发。


常见问题与注意事项

在使用 grid-template-rows 时,有一些细节需要注意:

  1. 必须设置 display: grid:否则该属性无效。
  2. 行数必须与子元素数量匹配:如果不匹配,多余的行会自动创建。
  3. fr 单位必须在总和中分配:不能单独使用,必须与其他单位一起。
  4. auto 会自动适应内容:但若内容过大,可能导致布局错乱,建议配合 min-height 使用。
  5. 避免使用 min-heightfr 冲突:如果设置 min-height: 100pxfr 单位,可能影响分配。

例如:

.container {
  display: grid;
  grid-template-rows: 1fr 1fr;
  min-height: 200px; /* 确保最小高度 */
}

这样可以防止内容过少时,行高被压缩到无法阅读。


总结

CSS grid-template-rows 属性是掌握 Grid 布局的关键一环。它让你能够精确控制每一行的高度,无论是固定值、百分比,还是响应式 fr 单位,都能轻松应对。

从简单的三行布局,到复杂的仪表盘设计,它都能提供强大的支持。通过结合 grid-template-columns,你可以构建出结构清晰、响应迅速、可维护性强的现代网页布局。

掌握这个属性,不仅提升你的布局能力,也能让你在前端开发中更具竞争力。继续练习,多写几个小案例,你会发现,用 Grid 布局构建页面,比传统的 float 或 flex 布局更直观、更高效。