CSS `Subgrid` 嵌套多层 `Grid` 布局的结构对齐与复杂数据展示

嘿,大家好!今天咱们来聊聊 CSS Grid 里的一个“隐藏大佬”—— Subgrid,以及它在复杂数据展示中如何大显身手。 别害怕,虽然名字听起来有点高大上,但其实理解起来并不难。我们尽量用大白话,加上代码示例,把它彻底搞明白。

开场白:Grid 的“儿子”和“孙子”们

话说 CSS Grid 布局已经很强大了,能把页面划分成一个个网格,随便你怎么摆放元素。 但有时候,你会遇到这样的情况:一个 Grid 容器里面,又嵌套了 Grid 容器,一层又一层。 这时候,如果想让这些嵌套的 Grid 容器里的元素,能够和最外层的 Grid 对齐,就有点麻烦了。

举个例子,一个电商网站的商品列表,每个商品是一个 Grid 容器。商品信息包括图片、名称、价格等等,它们也用 Grid 布局。 你想让所有商品的价格都能上下对齐,这就需要 Subgrid 出马了。

Subgrid:继承父辈光环,实现完美对齐

Subgrid 的作用,简单来说,就是让嵌套的 Grid 容器,“继承”父 Grid 的行列信息,从而实现对齐。 就像儿子继承了老子的基因一样,让孙子辈也能和爷爷辈的 Grid 对齐。

Subgrid 的基本用法

Subgrid 的关键在于 grid-template-columnsgrid-template-rows 这两个属性。 在子 Grid 容器上,你可以这样使用:

.parent {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr; /* 定义父 Grid 的列 */
  grid-template-rows: auto auto;      /* 定义父 Grid 的行 */
}

.child {
  display: grid;
  grid-column: 2;       /* 子 Grid 占据父 Grid 的第二列 */
  grid-row: 1;          /* 子 Grid 占据父 Grid 的第一行 */
  grid-template-columns: subgrid; /* 子 Grid 的列继承父 Grid */
  grid-template-rows: subgrid;    /* 子 Grid 的行继承父 Grid */
}

这段代码的意思是:

  1. .parent 是父 Grid 容器,定义了 3 列 2 行。
  2. .child 是子 Grid 容器,它占据了父 Grid 的第二列和第一行。
  3. grid-template-columns: subgrid;grid-template-rows: subgrid; 这两行代码是关键,它告诉浏览器,子 Grid 的行列信息,要继承父 Grid 的。

一个简单的例子:商品列表对齐

假设我们有这样一个 HTML 结构:

<div class="grid-container">
  <div class="item">
    <div class="image"></div>
    <div class="name">商品 A</div>
    <div class="price">199 元</div>
  </div>
  <div class="item">
    <div class="image"></div>
    <div class="name">商品 B</div>
    <div class="price">299 元</div>
  </div>
</div>

我们想让所有商品的价格都上下对齐。 可以这样写 CSS:

.grid-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr); /* 两列 */
  grid-gap: 20px;
}

.item {
  display: grid;
  grid-template-columns: subgrid; /* 继承父 Grid 的列 */
  grid-template-rows: auto auto auto;
}

.image {
  grid-column: 1;
  grid-row: 1;
}

.name {
  grid-column: 1;
  grid-row: 2;
}

.price {
  grid-column: 1;
  grid-row: 3;
}

在这个例子中,.item 是子 Grid 容器,它继承了 .grid-container 的列信息。 这样,所有商品的价格都会在同一列,从而实现对齐。

更复杂的例子:表格布局

Subgrid 在表格布局中也很有用。 比如,你想做一个复杂的表格,表头和数据都使用 Grid 布局,并且希望表头和数据能够完美对齐。

HTML 结构:

<div class="table">
  <div class="header">
    <div>Name</div>
    <div>Age</div>
    <div>City</div>
  </div>
  <div class="row">
    <div>Alice</div>
    <div>25</div>
    <div>New York</div>
  </div>
  <div class="row">
    <div>Bob</div>
    <div>30</div>
    <div>London</div>
  </div>
</div>

CSS 样式:

.table {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 三列 */
}

.header {
  display: grid;
  grid-template-columns: subgrid; /* 继承父 Grid 的列 */
}

.row {
  display: grid;
  grid-template-columns: subgrid; /* 继承父 Grid 的列 */
}

在这个例子中,.header.row 都继承了 .table 的列信息。 这样,表头和数据就能完美对齐了。

Subgrid 的一些高级用法

  • grid-column-startgrid-column-end: 你可以使用这两个属性,让子 Grid 占据父 Grid 的多列。 比如:

    .child {
      grid-column-start: 2;
      grid-column-end: 4; /* 子 Grid 占据父 Grid 的第二列到第四列 */
      grid-template-columns: subgrid;
    }
  • span 关键字: span 关键字可以用来指定子 Grid 占据父 Grid 的多少列。 比如:

    .child {
      grid-column: 2 / span 2; /* 子 Grid 从第二列开始,占据两列 */
      grid-template-columns: subgrid;
    }
  • 命名 Grid Lines: 你可以给 Grid 的行列线命名,然后在子 Grid 中使用这些名称。 这样可以提高代码的可读性。 比如:

    .parent {
      grid-template-columns: [col1] 1fr [col2] 2fr [col3] 1fr;
    }
    
    .child {
      grid-column: col2 / col3; /* 子 Grid 占据父 Grid 的 col2 到 col3 之间的列 */
      grid-template-columns: subgrid;
    }

Subgrid 的兼容性问题

虽然 Subgrid 很强大,但是它的兼容性并不完美。 目前,只有 Firefox 和 Safari 完整支持 Subgrid。 Chrome 和 Edge 也在逐步支持中。

所以,在使用 Subgrid 的时候,一定要注意兼容性问题。 可以使用一些 Polyfill 或者渐进增强的方法,来保证在不支持 Subgrid 的浏览器中,也能正常显示。

Subgrid 的优缺点

优点:

  • 简化复杂布局: Subgrid 可以让你更容易地创建复杂的、嵌套的 Grid 布局。
  • 实现完美对齐: Subgrid 可以让你轻松地实现元素之间的对齐。
  • 提高代码可读性: Subgrid 可以让你的代码更简洁、更易于理解。

缺点:

  • 兼容性问题: Subgrid 的兼容性并不完美,需要注意兼容性处理。
  • 学习曲线: Subgrid 的概念可能需要一些时间来理解。

Subgrid 的适用场景

  • 复杂的表格布局: 比如,带有分组表头、多级表头的表格。
  • 电商网站的商品列表: 需要保证所有商品的价格、名称等信息都对齐。
  • 后台管理系统的仪表盘: 需要将各种数据以网格的形式展示,并且保证对齐。
  • 任何需要嵌套 Grid 布局,并且需要对齐的场景。

Subgrid VS 常规Grid

特性 Subgrid 常规 Grid
嵌套 允许嵌套的 Grid 继承父 Grid 的行列信息 只能独立定义行列信息
对齐 能够实现嵌套 Grid 之间的对齐 需要额外的 CSS 技巧才能实现对齐
适用场景 复杂布局、需要对齐的场景 简单布局、不需要对齐的场景
兼容性 兼容性不如常规 Grid 兼容性更好
代码量 在复杂布局中,可以减少代码量 在复杂布局中,代码量可能较多

举例:用Subgrid实现一个复杂的日历

日历的布局,本身就是一个天然的网格结构,如果使用Subgrid来布局,可以非常方便地实现单元格对齐。

<div class="calendar">
  <div class="header">
    <div>Sun</div>
    <div>Mon</div>
    <div>Tue</div>
    <div>Wed</div>
    <div>Thu</div>
    <div>Fri</div>
    <div>Sat</div>
  </div>
  <div class="days">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>9</div>
    <div>10</div>
    <div>11</div>
    <div>12</div>
    <div>13</div>
    <div>14</div>
    <div>15</div>
    <div>16</div>
    <div>17</div>
    <div>18</div>
    <div>19</div>
    <div>20</div>
    <div>21</div>
    <div>22</div>
    <div>23</div>
    <div>24</div>
    <div>25</div>
    <div>26</div>
    <div>27</div>
    <div>28</div>
    <div>29</div>
    <div>30</div>
    <div>31</div>
  </div>
</div>
.calendar {
  display: grid;
  grid-template-columns: repeat(7, 1fr); /* 七列,对应一周七天 */
  grid-template-rows: auto 1fr;        /* 两行,一行表头,一行日期 */
}

.header {
  display: grid;
  grid-template-columns: subgrid;  /* 继承父Grid的列 */
}

.days {
  display: grid;
  grid-template-columns: subgrid;  /* 继承父Grid的列 */
  grid-gap: 5px;
}

.header div {
  text-align: center;
  font-weight: bold;
}

.days div {
  text-align: center;
  border: 1px solid #ccc;
  padding: 5px;
}

在这个例子中,.calendar 是最外层的 Grid,定义了日历的整体结构。.header.days 都使用了 subgrid,继承了父 Grid 的列信息,从而保证了表头和日期能够完美对齐。

总结:Subgrid,让 Grid 布局更上一层楼

Subgrid 是 CSS Grid 布局的一个强大补充,它可以让你更容易地创建复杂的、嵌套的 Grid 布局,并且实现元素之间的完美对齐。 虽然它的兼容性还不够完美,但是随着浏览器的不断发展,相信 Subgrid 会越来越普及。

希望今天的讲座能够帮助你理解 Subgrid,并在实际项目中灵活运用它。 记住,多实践,多尝试,才能真正掌握 Subgrid。

好了,今天的分享就到这里,谢谢大家! 咱们下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注