CSS3 最强二维布局系统之Grid 网格布局
深入学习 CSS3 目前最强大的布局系统 Grid 网格布局
Grid 网格布局的基本认识
Grid 网格布局: Grid 布局是一个基于网格的二位布局系统,是目前 CSS 最强的布局系统,它可以同时对列和行进行处理(它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局)
CSS 布局的过渡: CSS 一直用于对页面进行布局,但一直都不是很完美
1.一开始我们使用 table 做布局,然后转向浮动、定位以及 inline-block,但所有这些方法本质上都是 Hack 的方式,并且遗漏了很多重要的功能(例如垂直居中)
"Hack" 通常指的是一种快速、非标准或非预期的解决方案,用于绕过某些限制或问题
2. 随着 CSS3 的引入,特别是 Flexbox 和 Grid 布局的出现,网页布局变得更加直观和灵活,减少了对这些 “Hack” 方法的依赖,Flexbox 和 Grid 提供了更强大的布局控制,解决了许多历史遗留的布局问题,如垂直居中、响应式设计等
3. Flexbox 在一定程度上解决了这些问题,但它的目的是为了更简单的一维布局,而不是复杂的二维布局
4. Flexbox 布局是轴线布局,只能指定 "项目" 针对轴线的位置,可以看作是一维布局 → 而 Grid 布局则是将容器划分成 "行" 和 "列",产生单元格,然后指定 "项目所在" 的单元格,可以看作是二维布局(Grid 布局远比 Flex 布局强大)
5. Grid 布局是第一个专门为解决布局问题而生的 CSS 模块
术语: 在深入了解网格的概念之前,我们需要了解一些重要的术语
1. 网格容器与项目
容器(Container): 设置了 "display: gird / inline-grid" 的元素,就称之为网格容器(grid container)
项目(Item): grid 容器中的直接子元素就为网格项目(grid item)
.container {
display: gird
}+ 下面的 .container 元素就为网格容器(grid container),所有的直接子元素 .item 就为该网格容器的一个个项目(grid item)
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>2. 行和列: 容器里面的水平区域称为 "行"(row),垂直区域称为 "列"(column)

3. 单元格: 行和列的交叉区域,称为 "单元格"(cell)
4. 网格线: 划分网格的线,称为"网格线"(grid line),水平网格线划分出行,垂直网格线划分出列

Grid 网格布局的使用
Grid 网格布局的属性主要分为两类: 一类定义在容器上面,称为容器属性,另一类定义在项目上面,称为项目属性
容器属性
display: 将元素定义为 grid contaienr,并为其内容建立新的网格格式化上下文(grid formatting context)
grid- 生成一个块级 (block-level) 网格inline-grid- 生成一个行级 (inline-level) 网格subgrid- 如果你的 grid container 本身就是一个 grid item(即,嵌套网格),你可以使用这个属性来表示你想从它的父节点获取它的行/列的大小,而不是指定它自己的大小
.container {
display: grid | inline-grid | subgrid;
}tip: 注意:column, float, clear, 以及 vertical-align 对一个 grid container 没有影响(即设置这些属性了也无效)
grid-template-columns / grid-template-rows: 划分行和列,使用空格来分隔的多个值来定义网格的列和行
grid-template-columns:- 属性定义每一列的列宽grid-template-rows:- 属性定义每一行的行高
.container {
display: grid; /* 定义网格布局 */
grid-template-rows: 100px 100px 100px; /* 定义每一行行高 */
grid-template-columns: 100px 100px 100px; /* 定义每一列列宽 */
}
+ 上面代码指定了一个三行三列的网格,列宽和行高都为 100px
.item {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid white;
background-color: orange;
color: white;
}<body>
<span>H</span>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
<span>H</span>
</body>
repeat(count,any-value): - 有时候,重复写同样的值非常麻烦,尤其网格很多时 → 这时,可以使用repeat()函数,简化重复的值
+ 通过 repeat 函数来简化上面的写法
.container {
display: grid;
grid-template-rows: repeat(3, 100px);
grid-template-columns: repeat(3, 100px);
}auto-fill 关键字: - 有时,单元格的大小是固定的,但是容器的大小不确定 → 如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用 “auto-fill” 关键字表示自动填
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px); /* 具体多少列根据容器大小自动划分(每列列宽 100px) */
grid-template-rows: repeat(3, 100px);
}
+ 下图列数只是某一容器大小的示例图,并非所有,具体列数根据对应的容器大小与列宽有关
auto-fit 关键字:- 该关键字与上面的 auto-fill 的行为基本是相同的,都会尽可能的生成更多的列或行,但是两者也存在一点区别- auto-fill 不管单元格是否中是否有元素,都会生产对应单元格的空间
- auto-fit 则是如果单元格中没有元素时,会将对应的列宽收缩为 0
上面文字描述起来可能比较抽象,如下两图示例(为了更好的展示对应的区别,先将上面单元格的数量缩减成 3 个先)


