美文网首页
css grid 布局 详解+代码示例

css grid 布局 详解+代码示例

作者: LilyLaw | 来源:发表于2020-02-25 15:28 被阅读0次

    本文基于阮一峰大神的文章 http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html

    真诚建议大家去原文看,这篇文是我自己根据阮一峰的文章提炼要点,类似于自己的笔记和感悟。

    下面开始正题:

    grid 中文意思是网格,所以我们可以想象出,它大概是下面这个样子:

    grid.jpg

    每一个方块可以调,每一根线可以调,方块与方块的间距也可以调。

    (下面所有的示例,我先给一个完整代码,剩下的就简化了,方便大家查看)

    一、方块大小如何调?

    方块的大小说到点子上,也就是方块的widthheight 。调节widthheight ,基本就三种方式:

    • 绝对值,如 100px,10rem,10vh,10vw等。
    • 百分比,如 50%
    • 绝对值+百分比,如 calc(42% - 0.5rem) 等。(推荐大家去看看 calc,很好用哦~)

    (如果还有其他方式,欢迎大家评论中雅正)

    1. 在父元素上操作

    1.1 首先,父元素要声明自己是个grid布局的元素(块级或行内级):

    • 块级
    .container{
      display: grid; /* 一个块级的grid布局元素,展示效果为另起一行 */
    }
    

    效果图如下:

    块级grid
    • 行内级
    .container{
      display: inline-grid; /* 一个行内的grid布局元素,展示效果为与其他行内元素在一行*/
    }
    

    效果图如下:

    image.png

    1.2 声明完grid之后,要操作行和列

    • grid-template-columns 控制每一列的宽度
    • grid-template-rows 控制每一行的高度
      这两个属性的属性值可以有多种方式,下面我会一一举例
    1.2.1 绝对值

    比如 100px 10rem等具体的值。如下代码:
    一个三列两行的网格,这个很好理解,大家仔细看代码

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <style>
            .container{
                color: #fff;
                text-align: center;
                display: grid;
                grid-template-columns: 100px 200px 100px;  /* 三列 */
                grid-template-rows: 200px 100px;  /* 两行 */
            }
            .item:nth-child(1){background: #00aa00;}
            .item:nth-child(2){background: #0000ff;}
            .item:nth-child(3){background: #ff5500;}
            .item:nth-child(4){background: #ff00ff;}
            .item:nth-child(5){background: #aa0000;}
            .item:nth-child(6){background: #55007f;}
        </style>
    </head>
    <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>
    </body>
    </html>
    

    效果图如下:


    绝对值
    1.2.2 百分比

    注意,如果行的控制上也用百分比的话,grid元素要先设置height

    height:300px;
    grid-template-columns: 20% 50% 30%;  /* 三列 */
    grid-template-rows: 30% 70%; /* 两行 */ 
    

    效果图如下:

    百分比
    1.2.3 大招:一些神奇的属性值
    1.2.3.1 repeat()

    看这个属性设定

    grid-template-columns: 100px 100px 100px; /* 三列 */
    

    上面列数小,只有3列,所以可以枚举出来。但如果列数大了呢?比如12列,我们也枚举出来?是不是有点傻?
    repeat() 就可以解决这个问题

    repeat()接受两个参数,第一个参数是重复的次数(上例是3),第二个参数是所要重复的值

    所以可以写成

    grid-template-columns: repeat(3,100px); /* 绝对值 */
    grid-template-columns: repeat(3,33.33%); /* 百分比 */
    grid-template-columns: repeat(3,20px 50px 30px); /* 重复三遍模式,一共9列 */
    
    1.2.3.2 auto-fill

    有时候,里面的小格子大小固定,但外面的大容器大小不固定,想要小格子尽可能填充满大容器的每一行或每一列,这时可以用到auto-fill
    先看充满一行:

    grid-template-columns: repeat(auto-fill, 130px);    /* 尽可能充满一行 */
    

    效果图:

    尽可能充满一行

    充满一列

    height: 500px;
    grid-auto-flow: column; /* 先确定按列排 */
    grid-template-rows: repeat(auto-fill, 120px);
    

    效果图:

    尽可能充满一列
    1.2.3.3 fr

    网格布局提供了fr关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为1fr和2fr,就表示后者是前者的两倍。

    个人认为单纯使用fr来表示比例没有任何意义,和百分比效果一样,顶多是写法上更方便一些,因为不用计算百分比。fr和绝对值配合使用,才会发挥出巨大的作用

    比如说,现在有这么个需求:一个div,宽度随屏幕自适应,里面有三个元素排成一行,第一个元素100px的宽度,第三个元素宽度是第二个的二倍,要求三个元素充满整个div。我们就可以使用fr来实现。

      grid-template-columns: 100px 1fr 2fr;
    

    效果图如下:

    fr
    1.2.3.4 minmax()

    设置最小最大的范围。

    grid-template-columns: 100px 100px minmax(120px ,1fr);
    
    1.2.3.5 auto

    经常适用于以下场景:
    一个div,宽度随屏幕自适应,里面三个元素排成一行,第一个和第三个各100px,第二个充满剩余空间

    grid-template-columns: 100px auto 100px;
    

    效果图如下:

    auto

    二、网格线

    1. 指定网格线名称

    grid-template-columns属性和grid-template-rows属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用

    grid-template-columns: [cl1] 100px [cl2] auto [cl3] 100px [cl4];
    grid-template-rows: [rl1] 100px [2l2] auto [rl3];
    

    三、方块与方块的间距

    • 设置列间距 column-gap
    • 设置行间距 row-gap
    • gap: <row-gap> <column-gap>; 前两者简写形式
    grid-template-columns: [cl1] 100px [cl2] auto [cl3] 100px [cl4];
    grid-template-rows: [rl1] 100px [2l2] auto [rl3];
    column-gap: 10px;
    row-gap: 20px;
    

    效果图:

    image.png

    四、布局相关

    1. grid-template-areas

    grid布局会分出很多小单元格,这个属性就可以给单元格命名,方便引用

    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas: 'a b c'
                         'd e f'
                         'g h i';
    

    如上代码,九个单元格按照位置命名了。
    如果有些单元格,我们不需要引用,那么就不需要命名,该相对位置就用.代替:

    grid-template-areas: 'a . c'
                         'd e .'
                         'g . i';
    

    2. grid-auto-flow

    默认排列单元格的方式

    • 按行排: grid-auto-flow: row;
    • 按列排: grid-auto-flow: column;

    像不像flex布局里的 flex-direction

    grid-auto-flow: column;
    grid-template-columns:  50px  auto  50px ;
    grid-template-rows:  50px  auto ;
    

    效果图如下(仔细体会行和列哦,并没有改变,只是排列方式变了):

    按列排序

    ** 有一个 dense ** 的东西,指定某个单元格放在确定位置,其他的如何摆放,说实话我觉得用处不大,先不写了

    3. justify-items、align-items 、place-items

    • justify-items:单元格内容的水平位置
      主要有四个值:stretch | start | end | center。
      stretch是默认值,拉伸,占满整个单元格位置。
      给大家看一个start的完整代码。
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>JS Bin</title>
        <style type="text/css">
            #container{
                display: grid;
                grid-template-columns: 100px 100px 100px;
                grid-template-rows: 100px 100px 100px;
                justify-items: start;   /* start 布局 */
            }
            .item {
                font-size: 2em;
                text-align: center;
                border: 1px solid #000;
            }
            .item-1 {background-color: #ef342a;}
            .item-2 {background-color: #f68f26;}
            .item-3 {background-color: #4ba946;}
            .item-4 {background-color: #0376c2;}
            .item-5 {background-color: #c077af;}
            .item-6 {background-color: #f8d29d;}
            .item-7 {background-color: #b5a87f;}
            .item-8 {background-color: #d0e4a9;}
            .item-9 {background-color: #4dc7ec;}
        </style>
    </head>
    <body>
        <div id="container">
            <div class="item item-1">1</div>
            <div class="item item-2">2</div>
            <div class="item item-3">3</div>
            <div class="item item-4">4</div>
            <div class="item item-5">5</div>
            <div class="item item-6">6</div>
            <div class="item item-7">7</div>
            <div class="item item-8">8</div>
            <div class="item item-9">9</div>
        </div>
    </body>
    </html>
    

    效果图:

    start
    • align-items:单元格内容的垂直位置,与上面的justify-items 同理。
    • place-items:前面两者的合称

    4. justify-content、align-content、place-content

    • justify-content: 内容区域(那些聚在一起的单元格)在整个容器内水平方向的布局
      取值:start | end | center | stretch | space-around | space-between | space-evenly;
      start是默认值。
      举一个center的例子,下面是完整代码:
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>JS Bin</title>
        <style type="text/css">
            #container{
                display: grid;
                width: 500px;
                height: 500px;
                border: 1px solid #000000;
                grid-template-columns: 100px 100px 100px;
                grid-template-rows: 100px 100px 100px;
                justify-content: center;
            }
            .item-1 {background-color: #ef342a;}
            .item-2 {background-color: #f68f26;}
            .item-3 {background-color: #4ba946;}
            .item-4 {background-color: #0376c2;}
            .item-5 {background-color: #c077af;}
            .item-6 {background-color: #f8d29d;}
            .item-7 {background-color: #b5a87f;}
            .item-8 {background-color: #d0e4a9;}
            .item-9 {background-color: #4dc7ec;}
        </style>
    </head>
    <body>
        <div id="container">
            <div class="item item-1">1</div>
            <div class="item item-2">2</div>
            <div class="item item-3">3</div>
            <div class="item item-4">4</div>
            <div class="item item-5">5</div>
            <div class="item item-6">6</div>
            <div class="item item-7">7</div>
            <div class="item item-8">8</div>
            <div class="item item-9">9</div>
        </div>
    </body>
    </html>
    

    效果图:

    center
    • align-content : 内容区域(那些聚在一起的单元格)在整个容器内水平方向的布局
    • place-content属性是align-content属性和justify-content属性的合并简写形式。

    5. grid-auto-columns、grid-auto-rows

    比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。
    一个代码示例:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>JS Bin</title>
        <style type="text/css">
            #container{
                display: grid;
                width: 500px;
                height: 500px;
                border: 1px solid #000000;
                grid-template-columns: 100px 100px 100px;
                grid-template-rows: 100px 100px 100px;
            }
            
            .item-1 {background-color: #ef342a;}
            .item-2 {background-color: #f68f26;}
            .item-3 {background-color: #4ba946;}
            .item-4 {background-color: #0376c2;}
            .item-5 {background-color: #c077af;}
            .item-6 {background-color: #f8d29d;}
            .item-7 {background-color: #b5a87f;}
            .item-8 {background-color: #d0e4a9;}
            .item-9 {background-color: #4dc7ec;}
            
            .item-1{
                grid-row-start: 4;
                grid-row-start: 5;
            }
        </style>
    </head>
    <body>
        <div id="container">
            <div class="item item-1">1</div>
            <div class="item item-2">2</div>
            <div class="item item-3">3</div>
            <div class="item item-4">4</div>
            <div class="item item-5">5</div>
            <div class="item item-6">6</div>
            <div class="item item-7">7</div>
            <div class="item item-8">8</div>
            <div class="item item-9">9</div>
        </div>
    </body>
    </html>
    

    效果图:

    auto

    6. grid-column-start、grid-column-end、grid-row-start、grid-row-end

    指定某一项目的四个边框,从而指定某一项目的具体位置,如下代码:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>JS Bin</title>
        <style type="text/css">
            #container{
                display: grid;
                grid-template-columns: 100px 100px 100px ;
                grid-template-rows: 100px 100px 100px ;
            }
            
            .item-1 {background-color: #ef342a;}
            .item-2 {background-color: #f68f26;}
            .item-3 {background-color: #4ba946;}
            .item-4 {background-color: #0376c2;}
            .item-5 {background-color: #c077af;}
            .item-6 {background-color: #f8d29d;}
            .item-7 {background-color: #b5a87f;}
            .item-8 {background-color: #d0e4a9;}
            .item-9 {background-color: #4dc7ec;}
            
            .item-1{
                /* 指定位置 */
                grid-row-start: 2;
                grid-row-end: 3;
                grid-column-start: 2;
                grid-column-end: 3;
            }
        </style>
    </head>
    <body>
        <div id="container">
            <div class="item item-1">1</div>
            <div class="item item-2">2</div>
            <div class="item item-3">3</div>
            <div class="item item-4">4</div>
            <div class="item item-5">5</div>
            <div class="item item-6">6</div>
            <div class="item item-7">7</div>
            <div class="item item-8">8</div>
            <div class="item item-9">9</div>
        </div>
    </body>
    </html>
    

    效果图:

    设置位置

    7. grid-area

    指定项目放在哪一个区域,主要有两种方法

    7.1 直接指定区域

    #container{
        display: grid;
        grid-template-columns: 100px 100px 100px ;
        grid-template-rows: 100px 100px 100px ;
        grid-template-areas: 'a b c'
                             'd e f'
                             'g h i';
    }
            
    .item-1{
        grid-area: f;   /* 直接指定 */
    }
    

    7.2 通过线来指定区域

    #container{
        display: grid;
        grid-template-columns: 100px 100px 100px ;
        grid-template-rows: 100px 100px 100px ;
    }       
    .item-1{
        grid-area: 2/3/3/4;
    }
    

    8. justify-self、align-self、place-self

    设置单元格内容的水平或垂直位置,只作用于单个项目
    太简单了。。。跟上面justify-items一样的原理。

    到这儿就算完了,太不容易了,好懵。。。

    相关文章

      网友评论

          本文标题:css grid 布局 详解+代码示例

          本文链接:https://www.haomeiwen.com/subject/owyzqhtx.html