Grid(宫格)布局

562 阅读8分钟

1、Grid布局简述

Grid布局(宫格布局),它将网页分为一个个网格,利用这些网格组合做出各种各样的布局,Grid布局与Flex布局有一定的相似性,都能够指定容器内部多个成员的位置,不同之处,Flex是轴线布局,只能够指定成员相对于轴线的位置。Grid布局则是将容器划分为行和列,产生单元格,然后指定成员所在的单元格。

2、基础

通过指定display:grid指定容器使用Grid布局,Grid中采用网格布局的区域称为容器,容器内部采用网格定位的子元素称为成员。容器中水平区域称为行,垂直区域称为列,可以将其看为二维数组,划分网格的线称为网格线,正常情况下n行就有n+1根水平网格线,m列就有m+1根垂直网格线

注意:

当容器设置为Grid布局后,子元素的flot display:inline-block display:table-cell vertical-aligncolumn-*等都将失效

3、容器属性

grid-template-rows 和 grid-template-columns

grid-template-rows属性定义每一行的行高,设定为多少行就设置多少个值,取值可以为固定像素,也可以为百分比。grid-template-columns属性定义每一列的列宽,设定为多少列就设置多少个值,取值可以为固定像素,也可以为百分比。

    <div id="box">
        <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>
    #box {
            display: grid;
            grid-template-rows: 30px 30px 30px;
            grid-template-columns: 30px 30px 30px;
        }

repeat

repeat()函数可以简化重复的值,其可以自动重复设定的规则

    <div id="box">
        <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>
    #box {
            display: grid;
            grid-template-columns: repeat(3,30px 10px);/*表示重复3次 30px 10px*/
            grid-template-rows: repeat(3,30px);/*表示重复3次30px*/
        }

auto-fill

当单元格大小固定,但是容器大小不确定时,如果希望每一行或者每一列尽可能容纳多个单元格,这是可以使用auto-fill关键字表示自动填充,当容器不足容纳成员时会自适应换行

<div id="box" style="width: 60px;">
     <div>1</div>
     <div>2</div>
     <div>3</div>
 </div>
#box {
         display: grid;
         grid-template-columns: repeat(auto-fill,30px);
         grid-template-rows: repeat(3,30px);
     }

fr

表示比例关系,网格布局提供了fr关键字,如果两列的宽度分别为1fr2fr,就表示后者是前者的两倍

<div id="box">
     <div>1</div>
     <div>2</div>
     <div>3</div>
 </div>
#box {
         display: grid;
         grid-template-columns: 1fr 2fr 1fr;
         grid-template-rows: repeat(3,30px);
     }

minmax

minmax()函数产生一个长度范围,表示长度就在这个范围之中,它接受两个参数,分别为最小值和最大值,当距离不够时会从最大值自动减少长度或宽度到设定最小值为止。

minmax( [ <length> | <percentage> | min-content | max-content | auto ] , [ <length> | <percentage> | <flex> | min-content | max-content | auto ] )

<div id="box">
     <div>1</div>
     <div>2</div>
     <div>3</div>
 </div>
#box {
         display: grid;
         grid-template-columns: 30px minmax(30px,200px) 30px;
         grid-template-rows: repeat(3,30px);
     }

auto

auto关键字表示浏览器自己决定长度,基本上等于该列单元格的最大宽度,除非单元格内容设置了min-width,且这个值大于最大宽度

<div id="box">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>
#box {
         display: grid;
         grid-template-columns: 30px auto 30px;
         grid-template-rows: repeat(3,30px);
     }

grid-row-gap

grid-row-gap属性设置行与行的间距,即行间距

<div id="box">
      <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>
#box {
          display: grid;
          grid-template-columns: repeat(3,30px);
          grid-template-rows: repeat(3,30px);
          grid-row-gap: 10px;
      }

grid-column-gap

grid-column-gap属性设置列与列的间隔,即列间隔

  <div id="box">
        <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>
#box {
          display: grid;
          grid-template-columns: repeat(3,30px);
          grid-template-rows: repeat(3,30px);
          grid-row-gap: 10px;
          grid-column-gap: 10px;
      }

grid-gap

grid-gap属性是grid-column-gapgrid-row-gap的合并简写形式,如果grid-gap省略了第二个值,浏览器默认第二个值等于第一个值

  <div id="box">
        <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>
#box {
          display: grid;
          grid-template-columns: repeat(3,30px);
          grid-template-rows: repeat(3,30px);
          grid-gap: 10px;
      }

grid-template-areas

网格布局允许指定区域area,一个区域由单个或多个单元格组成,grid-template-areas属性用于定义区域。区域的命名影响到网格线。每个区域的起始网格线,会自动命名为{areaName}-start,终止线自动命名为{areaName}-end,不需要命名可写为.

grid-area 属性指定网格元素在网格布局中的大小和位置,是以下属性的简写属性:

  • grid-row-start
  • grid-column-start
  • grid-row-end
  • grid-column-end
<div class="container">
      <div class="red"></div>
      <div class="yellow"></div>
      <div class="green"></div>
      <div class="pink"></div>
      <div class="blue"></div>
      <div class="black"></div>
  </div>
.container {
      display: grid;
      width: calc(5 * 60px);
      height: calc(5 * 60px);
      padding: 60px;
      grid-template-rows: repeat(5, 60px);
      grid-template-columns: repeat(5, 60px);
      grid-template-areas:
          ".  red  red  red  . "
          "yellow .  .  .  . "
          "green  .  black  black  . "
          "green  .  .  .  blue "
          ".  pink pink pink . ";
  }

  .red {
      grid-area: red;
      background: red;
  }

  .yellow {
      grid-area: yellow;
      background: yellow;
  }

  .green {
      grid-area: green;
      background: green;
  }

  .pink {
      grid-area: pink;
      background: pink;
  }

  .blue {
      grid-area: blue;
      background: blue;
  }

  .black {
      grid-area: black;
      background: black;
  }

grid-auto-flow

划分网格后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是先行后列,通过设置grid-auto-flow可以更改为先列后行,grid-auto-flow属性除了设置为rowcolumn,还可以设置为row densecolumn dense,这两个值主要用于某些项目固定位置以后,剩下的项目如何放置

<div id="box">
  <div>F</div>
  <div>G</div>
  <div>H</div>
  <div>I</div>
</div>
#box{
      display: grid;
      grid-template-columns: repeat(2,30px);
      grid-template-rows: repeat(2,30px);
      grid-auto-flow: column;
  }

justify-items

justify-items属性设置成员中内容的水平位置,取值为start|end|center|stretch.

  • start对齐单元格的起始边缘
  • end对齐单元格的结束边缘
  • center单元格内部居中
  • stretch默认值:拉伸,占满单元格的整个宽度
<div class="box">
    <div>1</div>
</div>
.box {
        display: grid;
        justify-content: center;
   }

align-items

align-items属性设置成员中内容的垂直位置,取值为start|end|center|stretch.

  • start对齐单元格的起始边缘
  • end对齐单元格的结束边缘
  • center单元格内部居中
  • stretch默认值:拉伸,占满单元格的整个宽度
<div class="box">
    <div>1</div>
</div>
.box {
        display: grid;
        justify-content: center;
        align-items: center;
   }

place-items

place-items属性是align-itemsjustify-items的合并简写形式,如果省略第二个值,则浏览器默认为与第一个值相同

<div class="box">
    <div>1</div>
</div>
.box {
        display: grid;
        place-items: center center;
   }

justify-content

justify-content属性是整个内容区域在容器里面的水平位置,也就是成员的水平分布,取值为start|end|center|stretch|space-around|space-between|space-evenly.

.box {
        display: grid;
        grid-template-columns: repeat(3,30px);
        justify-content: space-between;
    }
<div class="box">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

align-content

align-content属性是整个内容区域在容器里面的垂直位置,也就是成员的垂直分布,取值为start|end|center|stretch|space-around|space-between|space-evenly.

<div class="box">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>
.box {
        height: 100px;
        display: grid;
        grid-template-columns: repeat(3,30px);
        justify-content: space-between;
        align-content: center;
    }

place-content

place-content属性是justify-contentalign-content的合并简写形式,如果省略第二个值,则浏览器默认与第一个值相同.

<div class="box">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>
.box {
        height: 100px;
        display: grid;
        grid-template-columns: repeat(3,30px);
        place-content: center space-between;
    }

grid-auto-columns grid-auto-rows

当项目的指定位置在现有网格的外部,比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。grid-auto-columns属性和grid-auto-rows属性来设置,浏览器会自动创建多余网格的列宽和行高,它们的写法与grid-template-columnsgrid-template-rows完全相同。如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高

<div class="box">
    <div>1</div>
    <div>1</div>
    <div>1</div>
</div>
.box {
        display: grid;
        grid-auto-rows: 100px;
        grid-auto-columns: 100px;
    }

4、项目属性

grid-column-start grid-column-end

grid-column-start属性指定左边框所在的垂直网格线, grid-column-end属性指定右边框线所在的垂直网格线。

<div class="box">
    <div class="box1">1</div>
</div>
.box {
        display: grid;
    }
.box1{
        grid-row-start: 2;
        grid-column-start: 2;
}

grid-row-start grid-row-end

grid-row-start属性指定上边框所在的水平网格线, grid-row-end属性指定下边框所在的水平网格线

<div class="box">
    <div class="box1">1</div>
</div>
.box {
        display: grid;
    }
.box1{
        grid-row-start: 2;
        grid-column-start: 2;
}

还可以通过给轴线命名的方式来指定位置

<div class="box">
    <div class="box1">1</div>
</div>
.box {
    display: grid;
    grid-template-rows: [r1] 30px [r2] 30px [r3];/*指定列,为轴线命名*/
    grid-template-columns: [c1] 30px [c2] 30px [c3];/*指定行,为轴线命名*/
 }
.box1 {
    grid-row-start: r2;
    grid-column-start: c2;
}

grid-column grid-row

grid-column属性是grid-column-startgrid-column-end的合并简写形式, grid-rowgrid-row-startgrid-row-end的合并简写形式。

<div class="box">
    <div class="box1">1</div>
</div>
.box {
    display: grid;
    grid-template-rows: repeat(2,30px);
    grid-template-columns: repeat(2,30px);
}
.box1{
    grid-column: 2/2;
    grid-row: 2/2;
}

grid-area

grid-area属性指定项目放在grid-template-areas指定的区域,还可以作用于grid-row-start grid-column-start grid-row-end grid-column-end的合并简写形式,直接指定项目的位置

<div class="box">
    <div class="box1">1</div>
    <div class="box2">2</div>
</div>
.box {
    display: grid;
    grid-template-rows: repeat(2, 30px);
    grid-template-columns: repeat(2, 30px);
    grid-template-areas: 'a b' 'c d'; 
}
.box1 {
    grid-area: b;
}
 .box2 {
    grid-area: 2/2/2/2; 
}

justify-self align-self place-self

justify-self属性设置单元格内容的水平位置,跟justify-items属性的用法完全一致,但只作用于单个项目,取值为start | end | center | stretch

align-self属性设置单元格内容的垂直位置,跟align-items属性的用法完全一致,也是只作用于单个项目,取值为start | end | center | stretch

  • stretch默认值:拉伸,占满单元格的整个宽度
  • start对齐单元格的起始边缘
  • end对齐单元格的结束边缘
  • center单元格内部居中 place-selfalign-self属性和justify-self属性的合并简写形式
<div class="box">
    <div class="box1">1</div>
</div>
.box {
    display: grid;
    grid-template-columns: repeat(2,30px);
    grid-template-rows: repeat(2,30px);
}

.box1 {
    place-self: center center;
}