Grid 布局-容器项

grid 网格布局是一个用于web的二维布局系统, 多行多列.

flex 单行布局则更倾向于一维布局, 一行或者一列.

Grid 重点

只是用表格进行排版哈, 横向内容直接无关联哦.

容器项 子项 布局应用
定义网格及 fr 单位 显式与隐式网格 叠加布局
合并网格及命名 基于线的元素放置 多种组合排列布局
网格间隙及简写 子项对齐方式 栅格布局
网格对齐方式及简写 repeat() 与 minmax() 容器自适应行列布局

Grid 容器项属性

因为是二维的, 这个属性的数量就比 flex 要多很多哦, 但其实真正也没有常用那没多啦.

A B
justify-items grid-template-rows
align-items grid-template-columns
place-items grai-template-areas
justify-content grid-template
align-content grid-row-gap
place-content grid-column-gap
grid-auto-flow grid-gap
grid-auto-rows /
grid-auto-columns /

定义网格和 fr 单位

这个 grid 和 表格 table 其实有点相像.

都是有行 row, 有列 column, 有单元格 cell, 有间隙 gap, 有合并单元格区域 area.

定义网格的行和列维度, 及其网格线名称, 轨道尺寸大小等, 主要用这两个属性:

  • grid-template-rows
  • grid-template-columns
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>grid-template</title>
  <style>
    .main {
      width: 300px;
      height: 200px;
      background-color: pink;

      /* 用 display 声明容器项是 grid */
      display: grid;
      /* 声明行列 */
      /* grid-template-rows: 100px 100px 100px; */
      /* grid-template-columns: 100px 100px 100px; */

      /* grid-template-rows: 50px 20% auto; */
      /* grid-template-columns: 50px 50px; */

      /* fr 分配空间, 类似 flex 的 1, 2, 这种 */
      grid-template-rows: 2fr 1fr;
      grid-template-columns: 1fr 1fr 1fr;
    }

    .main div {
      background-color: skyblue;
    }
  </style>
</head>
<body>
  <div class="main">
    <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>
</body>
</html>

合并网格及命名

grid-template-area 会以命名方式的形式定义网格区域, 即 合并单元格.

在子项上需要配合 grid-area 进行使用.

  • grid-template-rows + grid-template-columns
  • grid-template-areas
  • grid-area 子项引用
  • grid-template = 行列 + 合并区域

实战了一下, 确实通过 grid-template 简写的方式比较高效简洁哦:

grid-template: 
      "a1 a1 a2" 1fr 
      "a1 a1 a2" 1fr 
      "a3 a3 a3" 1fr 
      / 1fr 1fr 1fr;
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>grid-template-area</title>
  <style>
    .main {
      width: 300px;
      height: 200px;
      background-color: pink;

      display: grid;

      /* grid-template-rows: 1fr 1fr 1fr;
      grid-template-columns: 1fr 1fr 1fr;

      /* 自定义区域名字进行合并 */
      /* grid-template-areas: 
      "a1 a1 a2"
      "a1 a1 a2"
      "a3 a3 a3"; */

      /* grid-template 简写: 右边的 fr 表示行, 最下边的 '/ + fr' 表示列 */
      grid-template: 
      "a1 a1 a2" 1fr 
      "a1 a1 a2" 1fr 
      "a3 a3 a3" 1fr 
      / 1fr 1fr 1fr;

    }

    .main div {
      background-color: pink;
      box-sizing: border-box;
      border: 1px solid #000;
    }

    /* 子项上去使用 */
    .main div:nth-of-type(1) {
      grid-area: a1;
    }
    .main div:nth-of-type(2) {
      grid-area: a2;
    }
    .main div:nth-of-type(3) {
      grid-area: a3;
    }

  </style>
</head>
<body>
  <div class="main">
    <div>1</div>
    <div>2</div>
    <div>3</div>
  </div>
</body>
</html>

网格间隙及简写

主要是在容器项设置子项行列间的间隙大小, 主要这三个, grid-row-gap, grid-column-gap, grid-gap 单位了兼容其他容器的布局方式, 比如 flex, 因此我们更推荐使用时将 grid 前缀去掉, 即变成了:

  • row-gap
  • column-gap
  • gap

不论是 grid 还是 flex, 直接用 gap: xx px; 即设置好行列间隙啦.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>grid-gap</title>
  <style>
    .main {
      width: 300px;
      height: 200px;
      background-color: pink;
      display: grid;

      grid-template: 
      "a1 a1 a2" 1fr 
      "a1 a1 a2" 1fr 
      "a3 a3 a3" 1fr 
      / 1fr 1fr 1fr;

      /* 设置行列间距 */
      /* row-gap: 20px;
      column-gap: 30px; */

      /* gap 推荐复合写法, 先行后列 */
      gap: 10px 20px;
      
    }

    .main div {
      background-color: pink;
      box-sizing: border-box;
      border: 1px solid #000;
    }

    /* 子项上去使用 */
    .main div:nth-of-type(1) {
      grid-area: a1;
    }
    .main div:nth-of-type(2) {
      grid-area: a2;
    }
    .main div:nth-of-type(3) {
      grid-area: a3;
    }

    .main2 {
      /* 不给高度让它换行自动撑开 */
      width: 300px;
      background: pink;
      display: flex;
      flex-wrap: wrap;

      /* 和 grid 一样, 这个 gap 是通用的 */
      /* row-gap: 10px;
      column-gap: 20px; */

      /* 1个值写法, 给行列都设置10的间隙 */
      gap: 10px;
    }

    .main2 div {
      width: 100px;
      height: 100px;
      background-color: skyblue;
    }

  </style>
</head>
<body>
  <div class="main">
    <div>1</div>
    <div>2</div>
    <div>3</div>
  </div>
    
  <!-- 和 grid 一样, 这个 gap属性 是通用的 --> 
  <div class="main2">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
  </div>
</body>
</html>

网格对齐方式及简写

和 flex 对齐方式类似, 也是通过在容器项中, 设置在自行网格中的对齐方式来进行排版控制, 默认值是 strench 即是拉伸的, 它是设置每个子项相对自身区域的比如 左对齐, 居中, 靠上/靠下等.

容器尺寸小于网格区域尺寸时, 才能看到效果

  • justify-items
  • align-items
  • place-items

也是同上面的 gap 一样, 只要记住它是相对于子项自己区域的排列就好啦, 复合写法测一下就行不用记.

 /* 先垂直, 再水平, 不过不用记, 测试一把就知道啦 */
 place-items: end center;

还有与之相对于的三个属性, 它是设置整个网格对齐方式, 如左对齐, 居中, 靠上/靠下等.

容器尺寸大于元素尺寸时, 才能看到效果

  • justify-content
  • align-content
  • place-content

同理, 也是只要记住它是相对于整个网格的位置排列 就好啦, 复合写法测一下就行不用记.

/* 先上下, 后左右 不过不用记, 测试一把就知道啦 */
  place-content: start end;

当容器尺寸 <= 网格区域尺寸时, place-items:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>place-items</title>
  <style>
    .main {
      width: 300px;
      height: 200px;
      background-color: pink;

      display: grid;
      grid-template-rows: 100px 100px 100px;
      grid-template-columns: 100px 100px 100px;

      /* 当子项尺寸小于分配区域时, 相对于自身分配与的对齐 */
      /* start, center, end */
      /* justify-items: center;
      align-items: start; */

      /* 先垂直, 再水平, 不过不用记, 测试一把就知道啦 */
      place-items: end center;
    }

    .main div {
      /* 当子项尺寸小于分配区域时, 默认就会填不满容器 */
      width: 50px;
      height: 50px;
      background-color: skyblue;
    }
  </style>
</head>
<body>
  <div class="main">
    <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>
</body>
</html>

当容器尺寸 > 网格区域尺寸要大时, place-content:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>place-content</title>
  <style>
    .main {
      width: 500px;
      height: 500px;
      background-color: pink;

      display: grid;
      grid-template-rows: 100px 100px 100px;
      grid-template-columns: 100px 100px 100px;

      /* align-content: start;
      align-content: end; */

      /* 先上下, 后左右 不过不用记, 测试一把就知道啦 */
      /* place-content: start end; */

    }

    .main div {
      width: 50px;
      height: 50px;
      background-color: skyblue;
    }
  </style>
</head>
<body>
  <div class="main">
    <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>
</body>
</html>

但这个容器比整个网格尺寸要大的场景是非常小的, 通常都是会设置为一样的大小, 因此这个 place-content 属性应该是很少用到的啦, 但 place-items 却基本都会用到哦.

隐式网格于显式网格

用来设置在显式网格之外的隐式网格, 如何排列及尺寸大小, 也是对应三个属性:

  • grid-auto-fow
  • grid-auto-rows
  • grid-auto-colums
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>自适应行列排列 grid-auto-flow</title>
  <style>
    .main {
      width: 300px;
      height: 300px;
      background-color: pink;

      display: grid;

      /* 设置为 1x3, 多的部分就变成隐式网格了 */

      /* grid-template-rows: 100px; */
      /* grid-template-columns: 100px 100px 100px; */

      /* 默认 row 就是行产生隐式网格, 多出来的会自动折行 */
      /* grid-auto-flow: row; */
       /* 默认宽度会保持一致, 高度会拉伸, 但可调整 */
      /* grid-auto-rows: 100px; */


      /* 设置为 3x1, 要设置多的部分按列进行隐式网格折列, 否则会超出容器 */

      grid-template-rows: 100px 100px 100px;
      grid-template-columns: 100px;
      /* 需要手动设置折列了哦, 高度保持一致, 宽度拉伸 */
      grid-auto-flow: column;
      /* 但宽度也可以调整 */
      grid-auto-columns: 100px;

    }

    .main div {
      background-color: skyblue;
      border: 1px solid #000;
      box-sizing: border-box;
    }
  </style>
</head>
<body>
  <div class="main">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <!-- 隐式网格 -->
    <div>4</div>
    <div>5</div>
  </div>
</body>
</html>

关于 grid 布局, 容器项常用的属性就差不多啦, 看上去很多, 其实也不少, 关键是有个理解和能查询就行啦.

posted @ 2024-05-25 14:39  致于数据科学家的小陈  阅读(17)  评论(0编辑  收藏  举报