脚本网 > 网页制作 > css > CSS3 最强二维布局系统之Grid 网格布局

CSS3 最强二维布局系统之Grid 网格布局

admin css

深入学习 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 个先)