You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何用CSS Grid实现含层级数据的双轴表格布局?

解决双轴日程表格的Grid布局方案

我太懂这种卡在Grid布局里的感觉了——那些指南确实全面,但碰到这种左上角留白的双轴表格布局,很容易找不到精准的切入点。之前靠嵌套div堆布局的惯性,也会让你一时转不过弯来。咱们一步步拆解这个每周日程的布局问题:

核心需求梳理

你的数据结构是:

每周日程 → 每天0~n个分类 → 每个分类0~n道菜品
布局要求:左上角为空白区域(也就是星期列头和分类行头的交叉位置留空)

关键思路:用Grid的双轴定位替代嵌套div

之前嵌套div的思路是「按天分组,每组内再按分类分组」,但Grid可以直接把所有元素放在同一个容器里,通过网格线来定位每个部分,完全不需要嵌套层级。

步骤1:设计扁平的HTML结构

抛弃嵌套,把所有元素放在同一个网格容器里,包括:

  • 左上角空白块
  • 星期列头(周一到周日)
  • 分类行头(早餐、午餐等)
  • 每个菜品单元格

示例结构:

<div class="schedule-grid">
  <!-- 左上角空白 -->
  <div class="empty-corner"></div>
  
  <!-- 星期列头 -->
  <div class="day-header">周一</div>
  <div class="day-header">周二</div>
  <div class="day-header">周三</div>
  <div class="day-header">周四</div>
  <div class="day-header">周五</div>
  <div class="day-header">周六</div>
  <div class="day-header">周日</div>
  
  <!-- 分类行头 -->
  <div class="category-header">早餐</div>
  <div class="category-header">午餐</div>
  <div class="category-header">晚餐</div>
  <div class="category-header">加餐</div>
  
  <!-- 菜品单元格:对应「周一-早餐」 -->
  <div class="meal">豆浆</div>
  <div class="meal">包子</div>
  <!-- 对应「周一-午餐」 -->
  <div class="meal">宫保鸡丁</div>
  <div class="meal">清炒时蔬</div>
  <!-- 其他菜品以此类推... -->
</div>

步骤2:用Grid属性定义布局规则

核心是通过grid-template-columnsgrid-template-rows定义网格的行和列,再用grid-column/grid-row给每个元素定位:

.schedule-grid {
  display: grid;
  /* 列:第一列是分类行头的宽度,后面7列对应7天,均分剩余空间 */
  grid-template-columns: 120px repeat(7, 1fr);
  /* 行:第一行是星期列头的高度,后面每行对应一个分类,高度自适应内容 */
  grid-template-rows: 50px repeat(4, auto);
  /* 网格间距,模拟表格边框感 */
  gap: 1px;
  border: 1px solid #ddd;
  max-width: 1200px;
  margin: 20px auto;
}

/* 左上角空白块:占据第一行第一列 */
.empty-corner {
  grid-column: 1 / 2;
  grid-row: 1 / 2;
  background-color: #f5f5f5;
}

/* 星期列头:统一占据第一行,自动排列到第2~8列 */
.day-header {
  grid-row: 1;
  background-color: #eee;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  font-weight: bold;
}

/* 分类行头:统一占据第一列,自动排列到第2~5行 */
.category-header {
  grid-column: 1;
  background-color: #eee;
  display: flex;
  align-items: center;
  padding: 10px;
  font-weight: bold;
}

/* 菜品单元格:默认按顺序填充对应网格位置 */
.meal {
  padding: 10px;
  background-color: #fff;
  border: 1px solid #f0f0f0;
}

步骤3:动态数据的适配(如果是后端渲染)

如果你的日程是动态生成的,只需要给每个菜品计算对应的网格位置:

  • 星期索引(周一=2,周二=3...周日=8)对应grid-column
  • 分类索引(早餐=2,午餐=3...加餐=5)对应grid-row

比如用JS动态生成的话,伪代码逻辑:

// 假设days是星期数组,categories是分类数组,meals是菜品数组(含dayIndex和categoryIndex)
meals.forEach(meal => {
  const mealEl = document.createElement('div');
  mealEl.className = 'meal';
  mealEl.textContent = meal.name;
  // 计算网格位置:星期索引+2,分类索引+2(因为第一列/行是头)
  mealEl.style.gridColumn = meal.dayIndex + 2;
  mealEl.style.gridRow = meal.categoryIndex + 2;
  document.querySelector('.schedule-grid').appendChild(mealEl);
});

为什么这比嵌套div好?

  • 完全避免了多层嵌套的层级混乱,HTML结构更扁平清晰
  • Grid的双轴定位天然匹配你的「星期×分类」二维数据结构,对齐更精准
  • 后续修改布局(比如调整行/列宽度、添加新分类/星期)只需要修改CSS的grid-template属性,不需要动HTML结构

内容的提问来源于stack exchange,提问作者Timm

火山引擎 最新活动