Grid布局

2,053 阅读8分钟

Grid布局

学了就忘,忘了就学,文本仅为个人学习Grid的笔记&总结

Grid布局即网格布局,它是目前唯一一种CSS二维布局(flex布局是一维布局),是目前最强大的CSS布局方案。
使用Grid布局可以将网页划分成一个个网格,通过组合这些网格做出各种各样的布局效果。利用 Grid 布局,我们可以轻松实现类似下图布局。示例代码

Grid兼容性

基本概念

容器和项目

采用Grid布局的元素称为容器,如果给一个标签添加 display:grid 或者 display:inline-grid,那么这个元素就被称为容器,这个容器的所有顶层子元素称为项目。下面代码示例中.container所在的元素即为容器,容器内的六个div就是容器中的项目,注意是项目是顶层子元素,.item6所在div中的p标签不是项目,Grid布局只对项目生效。

    <div class="container">
        <div class="item1 common">item1</div>
        <div class="item2 common">item2</div>
        <div class="item3 common">item3</div>
        <div class="item4 common">item4</div>
        <div class="item5 common">item5</div>
        <div class="item6 common"><p>item6</p></div>
    </div>

行和列

容器内水平区域称为行(row),上图中item1、item2、item3组成了一行,容器内垂直区域称为列(column),上图中item1、item4、item7组成了一列。

单元格

行和列的交叉区域,称为单元格,上图中item1到item9都是单元格,正常情况下,m行和n列会产生m * n个单元格

网格线

网格线就是划分网格的线,正常情况下,m行有m+1跟水平网格线,n列有n+1跟垂直网格线
上图是一个3 * 3的网格,所以一共有4根水平网格线和4根垂直网格线

Grid容器属性

display | grid-template-columns | grid-template-rows | grid-row-gap | grid-column-gap | grid-gap | grid-template-areas | grid-auto-flow | justify-items | align-items | place-items | justify-content | align-content | place-content | grid-auto-columns | grid-auto-rows | grid-template | grid

1.display(该属性将标签设置为Grid布局容器)

使用display:grid,那么该容器是一个块级元素,使用display:inline-grid,则该容器为一个行内元素

    .container{
        display:grid
    }
    .container{
        display:inline-grid
    }

2.grid-template-columns(该属性定义每一列的列宽)和grid-template-rows(该属性定义每一行的行高)

    .container{
        display:grid;
        grid-template-columns:100px 100px 100px;
        grid-template-row:50px 50px;
    }

上面代码指定了一个两行三列的网格,行高50px,列宽100px

这两个属性也支持百分比

    .container{
        display:grid;
        grid-template-columns:33.33% 33.33% 33.33%;
        grid-template-row:50% 50%;
    }
repeat()函数

该函数接收两个参数,第一个参数为重复次数,第二个参数为需要重复的值,使用repeat函数可以简化重复的值,上面代码可以用repeat改写

    .container{
        display:grid;
        grid-template-columns:repeat(3,100px);
        grid-template-row:repeat(2,50px);
    }

使用repeat也可以重复某种模式

    .container{
        display:grid;
        grid-template-columns:repeat(2,100px 30px 50px);
    }
auto-fill关键字

当单元格大小固定但容器大小不确定时,可以使用auto-fill关键字进行自动填充,让一行或者一列尽可能多的容纳单元格

    .container{
        display:grid;
        grid-template-columns:repeat(auto-fill,100px);
        grid-auto-rows: 50px;
    }

test1.gif

fr关键字

fr关键字代表网格容器中可用空间的一等份。如果两行或两列的分别设置为1fr和2fr,就表示后者是前者的两倍

    .container{
        display: grid;
        grid-template-columns: 100px 1fr 2fr;
        grid-template-rows: repeat(3,50px);
        gap: 24px;
    }

test2.gif

minmax()函数

minmax()函数产生一个长度范围,接收两个参数,第一个参数为最小值,第二个为最大值

    .container{
        display: grid;
        grid-template-columns: 1fr 1fr minmax(100px,2fr);
    }

上述代码代表第三列的宽度最少为100px,最大不能超过2fr

auto关键字

auto关键字表示由浏览器自己决定长度,下面代码中第一第三列固定为200px,中间一列由浏览器自适应

    .container{
        display: grid;
        grid-template-columns: 200px auto 100px;
        grid-template-rows: repeat(3,50px);
        gap: 24px;
    }

test3.gif

3.grid-row-gap(该属性设置行间距)、grid-column-gap(该属性设置列间距)以及grid-gap(该属性为前两个属性简写)

注:根据最新标准,上面三个属性名的grid-前缀已经删除,可以写为row-gap、column-gap、gap

    .container{
        display: grid;
        grid-template-columns: repeat(3,1fr);
        grid-template-rows: repeat(3,50px);
        gap: 24px;//row-gap: 24px;column-gap: 24px;
    }

4.grid-template-areas(该属性定义区域,一个区域由一个或者多个单元格组成)

该属性一般与grid-area一起使用,grid-area属性指定项目放在哪一个区域内,下面代码示例中可以看到,使用 grid-template-columnsgrid-template-areas 划分出6个区域,其中 . 代表空的也就是没有用到该单元格,.item1、.item2、.item3中使用grid-area表示讲该类对应的元素放到grid-template-areas定义的区域内

    .container{
        display: grid;
        grid-template-columns: 100px 100px 100px;
        grid-template-areas: ". item1 item1" "item2 item3 item3";
        gap: 16px;
    }
    .item1{
        grid-area: item1;
    }
    .item2{
        grid-area: item2;
    }
    .item3{
        grid-area: item3;
    }

5.grid-auto-flow(该属性决定容器中的项目按照什么顺序排列,默认值为row,即先行后列,先填满第一行,再开始放入第二行)

    .container{
        display: grid;
        grid-template-columns: 100px 200px 100px;
        grid-auto-rows: 50px;
        gap: 16px;
        grid-auto-flow: row;
    }
    .item6 {
        grid-column: span 2;
    }

在上述示例中,由于单独设置了item6所占空间被排列到下一行产生多余空间,可以使用grid-auto-flow:row dense,表示尽可能填满表格

    .container{
        display: grid;
        grid-template-columns: 100px 200px 100px;
        grid-auto-rows: 50px;
        gap: 16px;
        grid-auto-flow: row dense;
    }
    .item6 {
        grid-column: span 2;
    }

同理,使用grid-auto-flow: column表示先列后行,此处不再赘述

6.justify-items(该属性设置单元格内容左中右的水平位置)、align-items(该属性设置单元格内容上中下的垂直位置)、place-items(为前两个属性合在一起的简写)

       justify-items:start | end | center | stretch;

stretch(默认值):拉伸,占满整个单元格的宽度

start:对齐单元格的起始边缘

end:对齐单元格的结束边缘

center:单元格内部居中

       align-items:start | end | center | stretch;

align-items垂直方向,效果同理只是改为垂直方向,此处不再赘述

7.justify-content(该属性是整个内容区域在容器里左中右的水平位置)、align-content(该属性是整个内容区域在容器里上中下的垂直位置位置)、place-content(为前两个属性的合并简写形式)

       justify-content: start | end | center | stretch | space-around | space-between | space-evenly;

start:对齐容器的起始边框

end:对齐容器的结束边框

center:容器的内部居中

space-around:每个项目的两侧间隔相等,项目之间的间隔比项目与容器边框的间隔大一倍

space-between:项目之间的间隔相等,项目与容器边框之间没有间隔

space-evenly:项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔

       align-content: start | end | center | stretch | space-around | space-between | space-evenly;

align-content垂直方向,效果同理只是改为垂直方向,此处不再赘述

8.grid-auto-columns、grid-auto-rows

有时候你定义了一个3行x3列的网格,但是item8指定在第四行,item9指定在第五行,这个时候使用grid-auto-columns、grid-auto-rows这两个属性让浏览器自动创建多余网格的列宽和行高,写法与grid-template-columns和grid-template-rows完全相同

   .container{
        display: grid;
        grid-template-columns: 100px 200px 100px;
        grid-template-rows:repeat(3,50px);
        gap: 16px;
        grid-auto-rows: 30px;
    }
    .item8 {
        grid-column: 2/3;
        grid-row: 4/5;
    }
    .item9 {
        grid-column: 3/4;
        grid-row: 5/6;
    }
    .common{
        background-color: #7f71fe;
        font-size: 18px;
        color: #fff;
        text-align: center;
    }
    <div class="container">
        <div class="item1 common">item1</div>
        <div class="item2 common">item2</div>
        <div class="item3 common">item3</div>
        <div class="item4 common">item4</div>
        <div class="item5 common">item5</div>
        <div class="item6 common">item6</div>
        <div class="item7 common">item7</div>
        <div class="item8 common">item8</div>
        <div class="item9 common">item9</div>
    </div>
    

Grid项目属性

grid-column-start | grid-column-end | grid-row-start | grid-row-end | grid-column | grid-row | grid-area | justify-self | align-self | place-self

1.grid-column-start(该属性表示左边框所在的垂直网格线)、grid-column-end(该属性表示右边框所在的垂直网格线)、grid-row-start(该属性表示上边框所在的水平网格线)、grid-row-end(该属性表示下边框所在的水平网格线)

    .item2 {
        grid-column-start: 2;
        grid-column-end: 4;
        grid-row-start:1;
        grid-row-end:3;
    }

上述代码表示item2的左边框是第二根网格线,右边框是第四根网格线,上边框是第一根网格线,下边框是第三根网格线

这四个属性的值还可以使用span

    .item2 {
        grid-column-start: span 2;
    }

注:使用这四个属性如果产生了重叠,则可以使用z-index指定项目的重叠顺序

2.grid-column(grid-column-start和grid-column-end合并简写)、grid-row(grid-row-start和grid-row-end合并简写)

    .item2 {
        grid-column-start: 2;
        grid-column-end: 4;
        grid-row-start:1;
        grid-row-end:3;
    }
    等同于
    .item2 {
        grid-column: 2 / 4;
        grid-row:1 / 3;
    }
    等同于
    .item2 {
        grid-column: 2 / span 2;
        grid-row:1 / span 2;
    }

3.grid-area(见上方grid-template-areas,此处不再赘述)

4.justify-self(该属性设置单元格内容左中右的水平位置)、align-self(该属性设置单元格内容上中下的垂直位置)、place-self(为前两个属性的合并简写)

       justify-self:start | end | center | stretch;
       align-self:start | end | center | stretch;

用法同justify-items和align-items,但只作用于单个项目

start:对齐单元格的起始边框

    .item1 {
        justify-self: start;
    }

其余同justify-items效果,区别只在于作用于单个项目

align-self垂直方向,效果同理只是改为垂直方向,此处不再赘述

参考文章:

《CSS Grid 网格布局教程》,作者:阮一峰
《最强大的CSS布局——Gird布局》,作者:Gopal