Grid网格布局 容器属性与子项属性 Grid实现自适应三栏布局

Grid 网格布局

网格布局是最强大的CSS布局方案,将网页划分成一个个网格
可以任意组合不同的网格,做出各种各样的布局

网格布局与弹性布局有一定的相似性,都可以指定容器内部多个项目的位置,
但是也存在重大区别

1.1 和flex布局的区别:

  • grid容器子项是单元格,而非子元素(当然,如果子元素没有设置宽高,那么他的宽高跟随单元格,值得一提的是,子元素样式calc函数的100%也是相对于单元格而非容器元素),而flex容器的子项直接即是子元素
  • Flex布局是轴线布局,只能指定"项目"针对轴线的位置,是一维布局
  • grid将容器划分成行和列,产生单元格,然后指定项目所在单元格,可以看作是二维布局

1.2 基本概念

容器和项目:即容器结点和子节点
行和列:水平区域/垂直区域
单元格:行和列的交叉区域,n行m列会产生n×m个单元格
网格线:划分网格的线,水平网格线和垂直网格线分别决定了行和列,n行有n+1根网格线

1.3 容器属性

  • Grid项目指子节点,不包含孙子节点,Grid子项(单元格)默认都是块级元素
  • 和flex布局一样,Grid布局不影响容器之外的元素
  • 设置Grid布局以后,容器子项的float、display等属性失效
  • 指定网格布局:display:grid

1.3.1 指定块级容器和行内容器

display:grid
display:inline-grid

1.3.2 列宽和行高

容器指定了网格布局以后,接着就要划分行和列
grid-template-columns: 每列列宽, 是设置子项(单元格)的属性,而不是子元素宽高,但是可以用calc函数相对于父元素做子元素计算
grid-template-rows:每行行高

有时候重复的值很多,写起来很麻烦,这时,可以使用repeat函数,简化重复的值
简写:
grid-template-columns:repeat(3, 33, 33%) 三列均分布局
grid-template-rows:repeat(3, 33.33%) 每行行高为33.33%

<style>

    .wrapper {
        height: 500px;
        width: 600px;
        display: grid;
        background: lightseagreen;
        /*  定义列宽。指的是子项(单元格)的宽度,而非子元素的宽度*/
        grid-template-columns: repeat(3, 200px);
        /* 定义每行行高 */
        grid-template-rows: 100px 100px 100px;
        /* repeat(3,200px) equals to 200px 200px 200px  */
    }
    .child {
        width: 100px;
        height: 100px;
        background: lightsalmon;
        font-size: 12px;
    }

</style>
<body>

    <div class="wrapper">
        <div class="child"><span>grandchild</span></div>
        <div class="child"><span>grandchild</span></div>
        <div class="child"><span>grandchild</span></div>
    </div>

</body>

1.3.3 自动填充 auto-fill关键字

有时候,单元格大小固定,但是容器的大小不固定,可以用这个属性包含尽可能多的列
即:不指定容器的列数,只指定容器的列宽,具体一行多少列数,由容器宽来做自适应,尽可能容纳更多的列数


    <style>
        .container{
            width: 430px;
            height: 500px;
            background: lightseagreen;
            display: grid;
            grid-template-columns: repeat(auto-fill,100px);
            grid-template-rows: repeat(3 200px);
            gap: 10px;
        }

        .item{
            width: 100px;
            height: 100px;
            background: lightsalmon;
        }
        
    </style>

<body>

    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>

</body>

1.3.4 比例关系 fr关键字

有时候为了方便表示比例关系,grid布局提供了fr关键字(fraction, 片段)
如果两列的宽分别为1fr 和 2fr 那么前者是后者的两倍
如果全是1fr, 表示均分
如果是100px 1fr 2fr, 则表示第一列100px, 剩下均分,但是第二列是第三列的1/2

 <style>

        .container{
            width: 530px;
            height: 500px;
            background: lightseagreen;
            display: grid;
            /* 4个单元格均分容器宽 */
            /* grid-template-columns: repeat(4,1fr); */
            /* 第一列宽200px,剩下3列均分剩余容器宽 */
            grid-template-columns: 200px repeat(3,1fr);
            grid-template-rows: repeat(3 200px);
            gap: 10px;
        }

        .item{
            /* 这个100%是相对于单元格,而非容器 */
            width: calc(100% - 10px);
            height: 100px;
            background: lightsalmon;
        }
        
    </style>

<body>

    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>

</body>

1.3.5 长度范围 minmax

minmax指定长度范围,如指定第一列列宽不小于100px不大于200px

<! DOCTYPE html>
<html lang="en">
<head>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

</head>

    <style>
        .container{
            width: 530px;
            height: 500px;
            background: lightseagreen;
            display: grid;
            /* 指定宽度范围,实际宽度190px,按最大情况处理,剩下fr均分 */
            grid-template-columns: minmax(100px,200px) repeat(3,1fr);
            grid-template-rows: repeat(3 200px);
            gap: 10px;
        }

        .item{
            /* 这个100%是相对于单元格,而非容器 */
            width: calc(100% - 10px);
            height: 100px;
            background: lightsalmon;
        }
        
    </style>

<body>

    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>

</body>
</html>

1.3.6 Grid实现两栏布局和三栏自适应布局

三栏布局,中间自适应, 将左右两栏写死,中间设置1fr自动分配即可

<style>

    body,
    html {
        width: 100%;
        height: 100%;
        /* 去掉滚动条 */
        margin: 0;
    }

    .container {
        width: 100%;
        height: 100%;
        background: lightseagreen;
        display: grid;
        /* 两栏布局 */
        /* grid-template-columns: 70% 30%; */
        /* 三栏布局,中间自适应,将左右两栏写死,中间设置1fr自适应分配即可 */
        grid-template-columns: 100px 1fr 200px;
        /*不写默认是100%,子元素默认撑满单元格高度 */
        /* grid-template-rows: 100px; */
    }
    .left {
        background: skyblue;
    }
    .right {
        background: rebeccapurple;
    }
    .con {
        background: orange;
    }

</style>

<body>

    <div class="container">
        <div class="left"></div>
        <div class="con"></div>
        <div class="right"></div>
    </div>

</body>

1.3.7 grid间隔

grid-row-gap:设置行间隔
grid-column-gap:设置列间隔
grid-gap: 设置行间隔于列间隔

<! DOCTYPE html>
<html lang="en">
<head>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

</head>

    <style>
        .container{
            width: 530px;
            height: 500px;
            background: lightseagreen;
            display: grid;
            grid-template-columns: repeat(3,1fr);
            gap: 10px 10px;
        }

        .item{
            background: lightsalmon;
        }
        
    </style>

<body>

    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>

</body>
</html>

1.3.8 grid-auto-flow属性

通过grid-template-columns和grid-template-rows设置好行列,确定好单元格之后
可以用grid-auto-flow来决定子元素是先填满行还是先填满列

<! DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

</head>
<style>

    .container {
        width: 930px;
        height: 900px;
        background: lightseagreen;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-template-rows: repeat(3, 1fr);
        gap: 10px 10px;
        /* 先行后列,默认,即子元素先填满行 */
        /* grid-auto-flow: row; */
        /* 先列后行,即子元素先填满第一列 */
        grid-auto-flow: column;
    }

    .item {
        width: 50px;
        height: 50px;
        background: lightsalmon;
    }

</style>

<body>

    <div class="container">
        <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 class="item">8</div>
        <div class="item">9</div>
    </div>

</body>

</html>

1.3.9 justify-items align-items justify-content align-content

justify-items align-items
设置的是单元格内容相对于单元格的水平/垂直位置
start:对齐单元格的起始边缘
end:对齐单元格的结束边缘
center:单元格内部居中
stretch:拉伸,占满单元格的整个宽度(默认值)

jusityfy-content align-content
设置的是整个内容区域在Grid容器中的位置
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;

<! DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

</head>
<style>

    .container {
        width: 930px;
        height: 900px;
        background: lightseagreen;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-template-rows: repeat(3, 1fr);
        gap: 10px 10px;
        /* justify-items/align-items设置单元格内容的水平/垂直位置 */
        justify-items: center;
        align-items: center;
    }

    .item {
        width: 50px;
        height: 50px;
        background: lightsalmon;
    }

</style>

<body>

    <div class="container">
        <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 class="item">8</div>
        <div class="item">9</div>
    </div>

</body>

</html>

1.4 子项属性

1.4.1 grid-columns-start/end 指定某个子项起止哪根网格线

<! DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

</head>
<style>

    .container {
        width: 930px;
        height: 900px;
        background: lightseagreen;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-template-rows: repeat(3, 1fr);
        gap: 10px 10px;
        /* 先行后列,默认,即子元素先填满行 */
        /* grid-auto-flow: row; */
        /* 先列后行,即子元素先填满第一列 */
        /* grid-auto-flow: column; */
    }

    .item {
        /* width: 100%; */
        /* height: 100%; */
        width: 50px;
        height: 50px;
        background: lightsalmon;
    }

    /* grid-column-start/end 第一个子元素起始于垂直第一根网格线,终止于垂直第三根网格线,共占据两个单元格  */
    .item:nth-child(1){
        width: 100%;
        background: red;
        grid-column-start: 1;
        grid-column-end: 3;
    }

</style>

<body>

    <div class="container">
        <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 class="item">8</div>
        <div class="item">9</div>
    </div>

</body>

</html>

1.4.2 grid-area 指定某个元素位于哪个区域

如以下位于区域e

.container {
        width: 930px;
        height: 900px;
        background: lightseagreen;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-template-rows: repeat(3, 1fr);
        gap: 10px 10px;
        /* justify-items/align-items设置单元格内容的水平/垂直位置 */
        /* justify-items: center; */
        /* align-items: center; */
        /* justify-content/align-content设置的是内容区域在整个Grid容器中的位置 */
        /* justify-content: space-between ; */
        grid-template-areas: 'a b c'
            'd e f'
            'g h i';
    }

    .item {
        /* width: 50px; */
        /* height: 50px; */
        background: lightsalmon;
    }

    .item:nth-child(1) {
        grid-area: e;
    }

1.4.3 jusity-slef align-self

设置单元格内容的水平/垂直位置,jusity-slef、align-self跟justify-items、align-self的用法效果相同,却别在于,前者是子项属性,只作用于某一个单元格,后者是容器属性,作用于所有单元格

如以下案例只会设置第一个子项水平在单元格内水平垂直居中

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    .container {
        width: 930px;
        height: 900px;
        background: lightseagreen;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-template-rows: repeat(3, 1fr);
        gap: 10px 10px;
        /* justify-items/align-items设置所有单元格内容的水平/垂直位置 */
        /* justify-items: center; */
        /* align-items: center; */
        /* justify-content/align-content设置的是内容区域在整个Grid容器中的位置 */
        /* justify-content: space-between ; */
    }

    .item {
        width: 100px;
        height: 100px;
        background: lightsalmon;
    }

    .item:nth-child(1) {
        /* 设置的是某个子元素在单元格内容中的水平/垂直位置 */
        justify-self: center;
        align-self: center;
    }
</style>

<body>
    <div class="container">
        <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 class="item">8</div>
        <div class="item">9</div>
    </div>
</body>

</html>

posted @ 2020-08-02 00:41  IslandZzzz  阅读(5035)  评论(0编辑  收藏  举报