布局 - Grid网格布局

184 阅读4分钟

基本概念

网格布局是将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。

  • 容器:一个案例中最大的盒子,可以理解为父元素
  • 项目:一个案例中,最大盒子里面的内容,可以理解为子元素

网格Grid布局 vs flex布局

  • Grid 布局是将容器划分成“行”和“列”,产生单元格,然后指定“项目位置”的单元格,可以看作是二维布局。
  • Flex 布局是轴线布局,只能指定“项目”针对于轴线的位置,可以看作是一维布局。
  • 网格布局中的属性和flex布局类似,主要分为两类,一是容器属性,二是项目属性。

网格属性

属性说明
displaydisplay: grid;(块级网格) / display: inline-grid;(行内块网格)
grid-template-rows规定行属性,取值个数决定有多少行
grid-template-columns规定列属性,取值个数决定有多少列
gap规定行列间距,是grid-gap的新版本写法,功能语法一样,例如,新版本 gap:15px 10px; 旧版本 grid-gap:15px 10px;行间距15px,列间距10px,这种写法是简写写法;包括row-gap(新版本) / grid-row-gap(旧版本)和 column-gap(新版本) / grid-column-gap(旧版本)
grid-template-areas将这个网格容器,分为多个区域,每个区域对应一个单元格,并通过grid-area制定项目名称
grid-auto-flow规定自动放置的项目如何插入网格中,row(默认,通过填充每一行来放置项目)/ column(填充每一列) / dense(填充任何地方) / row dense(填充行,且填充孔) / column dense(填充列,且填充孔)
place-content简写属性,place-content:<align-content> <justify-content>; 定义网格项目的水平和垂直对齐方式,取值包括 start / end / center / stretch / space-around / space-between / space-evenly,如果省略第二个值,则将第一个值同时分配给这两个属性

属性 1 定义网格

/* 1. 定义网格是 块级 还是 行内块 */
.parent-1{
    display: grid;  /* 块级网格,容器从上向下排列 */
}
.parent-2{
    display: inline-grid; /* 行内块网格,容器从左向右排列 */
}

属性 2 行列数量及宽度划分

/* 2. 定义网格的 行列划分 */
/* (1) 绝对大小*/
.parent{
    grid-template-columns: 200px 200px 200px;  /*每列间隔200px,一共三列*/
    grid-template-rows: 200px 200px;  /*每行间隔200px,一共三行*/
}
/* (2) 相对大小/百分比 */
.parent{
    grid-template-columns: 33.33% 33.33% 33.33%;  /*每列宽度33.33%,一共三列*/
    grid-template-rows: 33.33% 33.33% 33.33%;  /*每行宽度33.33%,一共三行*/
}
/* (3) 简写方式 1:repeat([个数,取值]) */
.parent{
    grid-template-columns: repeat(3, 33.3%);  /*每列宽度33.3%,chongfu */
    grid-template-rows: repeat(3, 33.3%);
}
/* (4) 简写方式 2:repeat(auto-fill,[取值])*/
.parent{
    grid-template-columns: repeat(auto-fill,33.33%);  /* 根据每列的宽度,自动分配有多少行 */
    grid-template-rows: repeat(auto-fil,33.33%);
}
/* (5) 片段 fr 等比例填充分布 */
.parent{
    grid-template-columns: 1fr 2fr 1fr; /* 中间一列占据空间是另外两列的2倍,相当于flex布局中的flex:1;效果 */
    grid-template-rows: 1fr 100px 100px; /* 1fr 相对于绝对大小而言 */
}
/* (6) 最小最大值 minmax */
.parent{
    grid-template-columns: minmax(100px, 200px) 200px 200px;
    grid-template-rows: 200px 200px 200px;
}
/* (7) 自动填满剩余空间 auto*/
.parent{
    grid-template-columns: 200px auto 150px;
    grid-template-rows: auto 180px 100px;
}

属性 3 行列间隔

/* 3. 定义网格 行列间隔 */
/* gap <-- grid-gap <-- grid-row-gap + grid-column-gap */
.parent{
    gap: 15px 10px; 
}

属性 4 网格区域、单元格名称

/* 4. 定义网格 区域及单元格名称 */
.parent{
    /* 网格区域 */
    grid-template-areas: 
                         "area_a area_a area_c"
                         "area_a area_a area_f"
                         "area_g area_h area_i";  /* 中间都是空格隔开,不能加逗号 */
}
.child-1{
    /* 单元格名称 */
    grid-area: area_a; /* 这里就会占据四个格子 */ 
}

属性 5 项目放置

/* 5.自动放置的项目如何插入 */
.parent-column{
    grid-auto-flow: column;  /*逐列插入项目*/
}
.parent-row{
    grid-auto-flow: row; /*逐行插入项目*/
}

属性 6 网格对齐方式

/* 6. 容器内网格整体的对齐方式: */
.child{
    place-content: end start; /* 左下角 */
}
/* 等同于如下两个 */
child{
    align-content: start;
    justify-content: end;
}

项目属性

属性 1 网格项目合并

属性说明
grid-column简写属性,格式为 grid-column:<grid-column-start>/<grid-column-end>; 前一个属性是左边框所在的垂直网格线,后面是右边框所在的垂直网格线
grid-row简写属性,格式为 grid-row:<grid-row-start>/<grid-row-end>; 前一个属性是上边框所在的水平网格线,后面是下边框所在的水平网格线
  • 如果一个m行n列的网格,需要(m+1)+(n+1)条线,m+1条横线,n+1条纵线
.parent{
    display: grid;
    grid-template-columns: repeat(3,33.33%);
    grid-template-rows: repeat(3,33.33%);
    gap: 10px;
}
.child:nth-child(1){
    background: url(./meng.jpg) no-repeat;
    background-size: cover;
}
.child:nth-child(2){
    background: url(./cb91f359b0.jpg) no-repeat;
    background-size: cover;
    
    /* grid-column-start: 2;
    grid-column-end: 4;
    grid-row-start: 1;
    grid-row-end: 3; */

    grid-column: 2/4;
    grid-row: 1/3;
}
.child:nth-child(3){
    background: url(./dfa6dd68bc.jpg) no-repeat;
    background-size: cover;
    grid-column: 1/2;
    grid-row: 2/4;
}
.child:nth-child(4){
    background: url(./920333fc0bb6239833eac5561adcb293.jpeg) no-repeat;
    background-size: cover;
    grid-column: 2/4;
    grid-row: 3/4;
}

网格项目合并示例.png

实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin:0;
            padding: 0;
        }
        html,body{
            height: 100%;
        }
        section{
            border: 5px solid black;
            width: 80%;
            height: 98%;
            margin: auto;
            /* 定义网格布局 */
            display: grid;
            /* 定义网格水平和垂直的列数和宽度 */
            grid-template-columns: minmax(100px,150px) 200px 200px;
            grid-template-rows: 200px 200px 200px;
            /* 定义网格各行列的水平和垂直间距 */
            gap: 20px 12px;
            /* 规划网格布局占位 */
            grid-template-areas: "a a b"
                                 "a a b"
                                 "c c d";
            /* 网格容器的对齐方式 */
            place-content: center;
        }
        div{
            outline: 1px solid black;
            text-align: center;
            font:normal bolder 100px/100px Aria;
            color: lightpink;
        }
        div:nth-child(1){ 
            background:url(./horse/horse.png) no-repeat center;
            background-size: 60%;
            /* 指定第一个元素占位在属于 a 的四个网格内 */
            grid-area: a;
        }
        div:nth-child(2){
            background: url(./zhangdan.svg) no-repeat center;
            background-size: cover;
            /* 指定第二个元素占位在属于 b 的两个网格内 */
            grid-area: b;
        }
        div:nth-child(3){
            background: url(./水波纹动态图.gif) no-repeat center;
            /* 指定第三个元素占位在属于 c 的两个网格内 */
            grid-area: c;
        }
        div:nth-child(4){
            background: url(./meng.jpg) center;
            background-size: contain;
            grid-area: d;
        }
    </style>
</head>
<body>
    <section>
        <div>a</div>
        <div>b</div>
        <div>c</div>
        <div>d</div>
    </section>
</body>
</html>

image.png