最全Grid布局教程——十分钟教会你使用Grid布局

8,238 阅读6分钟

Grid布局的基本概念

Grid 布局即网格布局,是一种新的 CSS 布局模型,比较擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系。用一组组相交的水平线和垂直线,用于定义列和行。元素可以放置在这些列行和行行内的网格上。

Grid 布局和 flex 布局

讲到布局,我们最常用的就是flex布局,是一种用于在项目之间分配空间的一维布局模型,一次只能处理一行或者一列。而grid布局是二维布局模型,通过行和列产生的网格来存放元素。看下面这个例子,可以看到使用Grid布局比使用flex布局不管结构样式都更加简洁

image-20241113115927388.png

  • flex布局

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <style>
    .box {
      width: 800px;
      height: 500px;
      background-color: #fac;
      font-size: 24px;
      font-weight: 700;
      margin: 100px auto;
      display: flex;
    }
    
    .box-left {
      flex: 1;
      margin-right: 10px;
      height: 100%;
      display: flex;
      flex-direction: column;
    }
    
    .box-left .item,
    .main .item,
    .header,
    .footer {
      padding: 30px;
      text-align: center;
      border: 1px solid #000;
    }
    
    .box-left .item:nth-child(1) {
      background: red;
      flex: 3;
    }
    
    .box-left .item:nth-child(2) {
      background: pink;
      margin: 10px 0;
      flex: 1;
    }
    
    .box-left .item:nth-child(3) {
      background: purple;
      flex: 1;
    }
    
    .box-right {
      flex: 2;
      height: 370px;
      display: flex;
      flex-direction: column;
    }
    
    .header {
      flex: 1;
      background: yellow;
    }
    
    .main {
      flex: 1;
      margin: 10px 0;
      display: flex;
    }
    
    .main .item:nth-child(1) {
      flex: 1;
      background: blue;
      margin-right: 10px;
    }
    
    .main .item:nth-child(2) {
      flex: 1;
      background: green;
    }
    
    .footer {
      flex: 1;
      background: orange;
    }
    
    </style>
    </head>
    <body>
      <div class="box">
          <div class="box-left">
            <div class="item">1</div>
            <div class="item">5</div>
            <div class="item">7</div>
          </div>
          <div class="box-right">
              <div class="header">2</div>
              <div class="main">
                  <div class="item">3</div>
                  <div class="item">4</div>
              </div>
              <div class="footer">6</div>
          </div>
       </div>
    </body>
    </html>
    
  • grid布局:可以通过简短的代码布局成这样

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <style>
       .item {
          padding: 30px;
          text-align: center;
          border: 1px solid #000;
        }
    
       .box {
          width: 800px;
          height: 500px;
          background-color: #fac;
          font-size: 24px;
          font-weight: 700;
          margin: 100px auto;
          display: grid;
          grid-gap: 10px;
          grid-template: repeat(3, auto) / repeat(3, auto);
    
        }
    
        .item:nth-child(1) {
          grid-row-start: span 2;
          background: red;
        }
    
        .item:nth-child(2) {
          grid-column-start: span 2;
          background: yellow;
        }
    
        .item:nth-child(3) {
          background: blue;
        }
    
        .item:nth-child(4) {
          background: green;
        }
    
        .item:nth-child(5) {
          background: pink;
        }
    
        .item:nth-child(6) {
          background: orange;
          grid-column-start: span 2;
        }
    
        .item:nth-child(7) {
          background: purple;
        }
     </style>
    </head>
    <body>
     <div class="box">
        <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>
    </body>
    </html>
    

设置为网格布局

当 HTML 元素的 display 属性设置为 gridinline-grid 时,它就会成为网格容器。

.box{
    display:grid;
    /* 或 */
    diaplay:inline-grid
}

容器属性

grid-template-columns

定义网格布局中的列数。grid-template-rows:定义网格布局中的行数。以grid-template-columns为例,grid-template-rows用法和列一至。

属性值

  • 100px 100px——一个值代表一列,以此类推(常用单位都可以)。

image-20240905144557145.png

  • repeat(重复次数,每一列宽)——简化重复的值,就像上面两列的宽度都是100px,我们可以这样实现,效果一样repeat(2,100px)

  • span关键字——表示跨度,span 2表示跨两个单元格

  • auto-fill关键字——是repeat函数重复次数的关键字,表示自动填充,尽量容纳更多格子(因为最外面的大盒子是800px,每个列宽是150px,所有最多放下5个格子)

image-20240905144659026.png

  • fr关键字——表示份数(把盒子分成n份),1fr表示占box盒子其中一份,这里代码表示第一列占一份(1/3),第二列占两份(2/3)

image-20240905151508758.png

  • minmax(最小值,最大值)——表示最小宽度不能低于最小值,最大宽度不能超过最大值,这里代码表示第一列最小不能低于100px,最大宽度不能超过200px,在这区间都可以

image-20240905150910502.png

  • auto关键字——表示由浏览器自己决定长度,这里代码表示第一列长度为200px,第三列长度为100px,中间的由浏览器决定

image-20240905151842511.png

  • fit-content()函数——表示让宽度适应内容,但不超过设定的尺寸,注意这里不能使用fr关键字,这里代码表示第一列宽根据内容长度改变,但不能超过100px

image-20240905153137157.png

grid-template

grid-template-columnsgrid-template-rowsgrid-template-areas的简写形式。这里代码表示双引号里面定义区域后面加那一行的行高,最后/后面添加列宽

image-20240905172157574.png

grid-column-gapcolumn-gapgrid-row-gaprow-gap

grid-column-gapcolumn-gap:定义列间距。 grid-row-gaprow-gap:定义行间距

image-20240905155730799.png

grid-gap

定义行列间距,是grid-column-gapgrid-row-gap的简写形式,有两个值,前面那个是行间距,后面那个是列间距,如果只有一个值表示行列间距都是它

image-20240905160010984.png

grid-template-areas

用于定义区域,一个区域由一个或者多个单元格组成,一般这个属性跟项目属性grid-area一起使用,注意.表示没有用到该格子。在grid-template-areas声明区域名称,grid-area在子项样式里使用grid-template-areas所声明的区域名称,注意不要加引号,否则不生效

image-20240905163853055.png

grid-auto-flow: [ row | column ] || dense

控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。默认放置顺序是“先行后列”,类似flex布局中的 flex-direction属性

  • row:默认水平排序

image-20241111103854695.png

  • column:以列排序

image-20241111113215423.png

  • dense:该关键字指定自动布局算法使用一种“稠密”堆积算法,如果后面出现了稍小的元素,则会试图去填充网格中前面留下的空白。row dense:等同于dense,空白部分以行的方式补上去

image-20241111113459428.png

  • column dense:空白部分以列的方式补上去

image-20241111112839275.png

justify-itemsalign-itemsplace-items

控制子项相对于单元格的水平垂直方向,如果子项没有设置宽高,会以内容大小为主。值为[start | end | center | stretch]place-items是组合写法:place-items:垂直 水平;

image-20241113094143648.png

justify-contentalign-contentplace-content

控制内容相对于容器的水平垂直方向,如果内容和容器大小一样设置则无效。值为[center | stretch | space-around | space-between | space-evenly]place-items是组合写法:place-items:垂直 水平;

image-20241113100611919.png

grid-auto-rowsgrid-auto-columns

grid-auto-rows:用于定义在显式网格之外的隐式网格中的行的高度。 grid-auto-columns:用于定义在显式网格之外的隐式网格中的列的宽度。单位和上面一样,以grid-auto-rows为例:

image-20241111115929812.png

项目属性

grid-[column || row]-startgrid-[column || row]-endgrid-[column || row]:grid-[column || row]-start / grid-[column || row]-end

可以指定网格项目定位在哪根网格线上,当有冲突的时候可以使用z-index提升它们的层级

image-20241113102240043.png

grid-area

配合容器属性 grid-template-areas的值来定义区域,上面介绍 grid-template-areas有提到

justify-selfalign-selfplace-self

控制子项相对于单元格的水平垂直方向。跟容器属性justify-items用法一样,只不过前面只能控制一个,后面控制全部。

image-20241113103909718.png