grid布局

Flex布局是轴线布局,只能指定“项目”针对轴线的位置,可以看做是一维布局;
Grid布局是将容器划分成“行“和”列“,产生单元格,然后指定”项目所在“单元格,可以看成是二维布局。

一、基本概念

1.1、容器和项目

  采用网格布局的区域,称为“容器”(container),容器内部采用网格定位的子元素称为“项目”(item)。

<div class="container">
    <div class="item"><p>1</p></div>
    <div class="item"><p>2</p></div>
    <div class="item"><p>3</p></div>
</div>

  上述代码中,最外层div.container元素为容器,内层div.item元素是为项目。项目只能是容器的顶层子元素,不包含项目的子元素,如<p>元素,Grid布局只对项目生效。

 

1.2、行和列 

  容器里面的水平区域称为“行”(row),垂直区域称为“列”(column)。

 1.3、单元格

  行和列交叉区域,称为“单元格”(cell)。

  正常情况下,n行和m列会产生n x m 个单元格,比如3行3列产生9个单元格。

 

1.4、网格线

  划分网格的线,称为“网格线”(grid line)。水平网格线划分出行,垂直网格线划分出列。

  正常情况下,n行有n + 1根水平网格线,m行有m + 1根垂直网格线。

  4 x 4的网格,共5根水平网格线和5根垂直网格线:

 

 

 

二、容器属性

Grid布局的属性分为两类,一类定义在容器上面,称为容器属性;另一类定义在项目上面,称为项目属性。

2.1、display属性

  display: grid 指定一个容器采用网格布局(display: inline-grid,将容器变成行内元素)。

  注:设为网格布局以后,容器子元素(项目)的float、display:inline-block | table-cell、vertical-align 和column-*等属性将失效。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {padding: 30px}
        .container {
            display: grid;
            grid-template-columns: 80px 80px 80px;
            grid-template-rows: 80px 80px 80px;
            width: max-content;
            margin: 10px 0;
            background: linear-gradient(135deg, #f9bcc6, #73a3ef);
        }
        .item {
            text-align: center;
            line-height: 80px;
            color: #fff;
            font-size: 20px;
            border: 1px solid #fff;
        }
        span {font-size: 20px;}
    </style>
</head>
<body>
<span>display</span>
<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>
<span>grid</span>
</body>
</html>

 

2.2、grid-template-columns、grid-template-rows属性

  容器指定了网格布局以后,接着要划分行和列。

  grid-template-columns:定义每一列的列宽, grid-template-rows:定义每一行的行高。

  列宽行高如果使用的是百分比值,则容器需要添加具体宽高值。  

.container {
    display: grid;
    grid-template-columns: 80px 80px 80px;
    grid-template-rows: 80px 80px 80px;
    width: max-content;
    margin: 10px 0;
    background: linear-gradient(135deg, #f9bcc6, #73a3ef);

    /*除了使用绝对单位,也可以使用百分比, 这时候需要指定容器宽高*/
    grid-template-columns: 33.33% 33.33% 33.33%;
    grid-template-rows: 33.33% 33.33% 33.33%;  
    width: 240px;
    height: 240px;
}

  

  1)repeat()函数

  在网格很多,重复写相同值的时候,可以使用repeat()函数简化重复的值。

  repeat():接受俩参数,第一个是重复的次数,第二个是重复的值或重复某种模式。

.container {
    grid-template-columns: repeat(3, 80px);
    grid-template-rows: repeat(3, 80px);

    grid-template-columns: repeat(3, 33.33%);
    grid-template-rows: repeat(3, 33.33%);
}
<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        body {padding: 30px}
        .container {
            display: inline-grid;
            /*grid-template-columns: repeat(3, 80px);*/
            grid-template-columns: repeat(2, 60px 80px 100px);
            grid-template-rows: repeat(3, 80px);
            width: max-content;
            height: max-content;
            margin: 10px 0;
            border: 1px solid #000;
            background: linear-gradient(135deg, #f9bcc6, #73a3ef);
        }
        .item {
            text-align: center;
            line-height: 80px;
            color: #fff;
            font-size: 20px;
            border: 1px solid #fff;
        }
    </style>
    <meta charset="UTF-8">
    <title>Title</title>
</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 class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
</div>
</body>
</html>

说明:

  上述图可以说明,当容器width和height未设置具体值时,由grid-template-columns和grid-template-rows决定;如果设置具体值如200px,则超出容器的项目不显示。

  容器的列数可以等于repeat()函数参数的重复次数 x 重复值项数(只有一项) 或 重复次数 x 模式中列数。

  图一:3 x 1(80px) =  1 x 3 ( 80px 80px 80px)

  图二:2 x 3 (60px 80px 100px) = 6列,这里虽然把第二行变成了列,但由于grid-template-rows: repeat(3, 80px),故容器的高依然为3个行高。

  图三:当把第二行变成第一行后,改变容器项目的总行高,才能改变容器整体高度。

 

  2)auto-fill 关键字

  在单元格大小固定、容器大小不确定情况下,如果希望每一行或每一列尽可能容纳更多单元格时,可以使用auto-fill关键字表示自动填充。

.container {
    display: grid;
    grid-template-columns: repeat(auto-fill, 100px);
    grid-template-rows: repeat(3, 100px);
    padding: 5px;
    background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}

  

  3)fr 关键字

  网格布局提供了fr关键字(fraction,片段)。很好的表达了比例关系。如下第二列为第一列的两倍,第三列为第一列的三倍。

  fr 可以与绝对长度单位结合使用(grid-template-columns: 120px 1fr 2fr)

.container {
    display: grid;
    grid-template-columns: 1fr 2fr;
    padding: 5px;
    background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}

 

  4)minmax( minValue,  maxValue ) 

  该函数产生一个长度范围,表示长度就在这个范围之中,接受两个参数,分别表示最小值和最大值。

.container {
    display: grid;
    grid-template-columns: 1fr 1fr minmax(100px, 1fr);
    padding: 5px;
    background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}

 

   5)auto 关键字

  表示该列列宽由浏览器决定,占据剩余宽度,当该列某单元格设置宽度大于该列分得的宽度时,该列宽同某单元格宽度相等,也就是基本上等于该列单元格中最大的宽度。

.container {
    display: grid;
    grid-template-columns: 100px auto 100px;
    padding: 5px;
    background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}

 

  6)网格线名称 

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

  如下,c1~c4为水平网格线,r1~r4为垂直网格线,网格线可以有多个名称,[c1] —> [c1  lineFirst]

.container {
    display: grid;
    grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
    grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
    padding: 5px;
    background: linear-gradient(135deg, #f9bcc6, #73a3ef);
}

  

  7)布局实例

  grid-template-columns属性对于网页布局非常有用,两栏布局只需要一行代码。  

 

2.3、grid-row-gap 、grid-column-gap、grid-grap属性

  grip-row-gap:设置行与行的间隔(行间距);

  grip-column-gap:设置列与列的间隔(列间距);

  grip-gap:是grip-row-gap和grip-column-gap的合并简写形式,grip-gap: <grip-row-gap> <grid-column-gap>。如果grip省略了第二个值,则默认第二个值等于第一个值。

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

 

2.4、grid-template-areas属性

  网格布局允许指定“区域”(area),一个区域由单个或多个单元格组成。

  以下代码先划分9个单元格,然后将其命名为a到i的9个区域,分别对应9个单元格:

.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';
}

  

  多个单元格合并一个区域的写法,将9个单元格分成a、b、c三个区域:

.container {
  grid-template-areas: 'a a a'
                       'b b b'
                       'c c c';  
}

  

  布局实例,顶部是页眉区域header,底部时页脚区域footer,中间部分则分为main和sidebar:

.container {
  grid-template-areas: 'header  header  header'
                       'main    main    main'
                       'footer  footer  footer';  
}

   

  如果某些区域不需要利用,则使用"点“(.)表示,中间一列为点,表示没有用到该单元格,或者该单元格不属于任何区域:

.container {
  grid-template-areas: 'a . a'
                       'b . b'
                       'c . c';  
}

   注:区域的命名会影响到网格线。每个区域的起始网格线自动命名为 区域名-start,终止网格线自动命名为 区域名-end。

      比如,区域名为header,则起始位置的水平网格线、垂直网格线叫做 header-start,终止位置的水平网格线、垂直网格线叫做 header-end。

 

2.5、grid-auto-flow 属性

  划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认放置顺序是“先行后列”,即先填满第一行,再开始放入第二行。

  这个顺序由grid-auto-flow属性决定,默认值是row,即“先行后列”,也可以设成column,变成“先列后行”。

 

   row dense属性值表示“先行后列”、column dense属性值表示“先列后行”,并且尽可能紧密填满,尽量不要出现空格(grid-column-start:1 应该表示改子项目从第一列开始排,第三列前结束,则占两个单元格)。  

 

2.6、justify-items属性、align-items属性、place-items属性

  justify-items:start | center | end | stretch; 设置单元格内容水平位置(左中右);

  align-items:start | center | end | stretch; 设置单元格内容垂直位置(上中下);

  place-items: <align-items> <justify-items>合并简写,place-items: start start,如果省略第二个值,则默认和第一个值相等。

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

  center:单元格内部居中;

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

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

 

2.7、justify-content属性、align-content属性、place-content属性

  justify-content:整个内容区域在容器里面的水平位置(左中右);

  align-content:整个内容区域在容器里面的垂直位置(上中下);

  place-content:<justify-content> <align-content> 合并简写,place-content: end end,如果省略第二个值,则默认和第一个值相等。

  start:对齐容器起始边框;

  center:容器内部居中;

  end:对齐容器结束边框;

  stretch:项目大小没有指定时,拉伸占满整个网格容器;

  space-around:每个项目两侧间隔相等。所以,项目中间间隔比项目是项目与容器边框间隔的两倍;

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

  space-evenly:项目与项目间隔和项目与容器边框间隔相等;

 2.8、grid-auto-columns属性、grid-auto-rows属性

  当项目被指定位置,并出现在现有网格外部时,浏览器会自动生成多余网格,以便放置项目,比如3行3列的网格存在第四列第四行时:

  grid-auto-columns:多余列网格的列宽;

  grid-auto-rows:多余行网格的行高;

  写法和grid-template-columns和grid-template-rows同。

  

2.9、grid-template属性、grid属性

  grid-template: grid-template-columns  grid-template-rows  grid-template-areas;

  grid: grid-template-rows  grid-template-columns  grid-template-areas  grid-auto-rows  grid-auto-columns  grid-auto-flow;


 

三、项目属性

1.1、grid-columns-start属性、grid-columns-end属性、grid-row-start属性、grid-row-end属性

  项目的位置可以指定,具体方法是指定项目的四个边框,分别定位在哪根网格线,网格线属性值也可以用名称、关键字span表示。

  使用这四个属性,如果产生项目重叠,则使用z-index属性指定项目重叠顺序。

  grid-column-start:左边框所在的垂直网格线;

  grid-column-end:右边框所在的垂直网格线;

  grid-row-start:上边框所在的水平网格线;

  grid-row-end:下边框所在的水平网格线;

    说明:第一个项目设置左边框是第二根垂直网格线,右边框是第四根垂直网格线。

 

   网格线用名称表示:

   

  span关键字表示:表示跨越,即左右边框或上下边框之间跨越多少个网格。

  grid-column-startr: span 2;表项目左边框距离右边框跨越2个网格;

  grid-column-end: span 2;表项目右边框距离左边框跨越2个网格;

 

1.2、grid-column属性、grid-row属性

  grid-column:grid-column-start和grid-column-end的合并简写,grid-column: <start-line> / <end-line>;

  grid-row:grid-row-start和grid-row-end的合并简写,grid-row: <start-line> / <end-line>;

 

 

 

 1.3、grid-area属性

  grid-area指定项目放在哪一个区域(同容器属性grid-column-area结合使用)。

  grid-area:可用作grid-row-start、grid-column-start、grid-row-end、grid-column-end结合使用。

  grid-area: <grid-row-start> / <grid-column-start> / <grid-row-end> / <grid-column-end>

 

1.4、justify-self属性、align-self属性、place-self属性

  justify-self:设置单元格内容水平位置(左中右),同justify-items属性用法一致,但只作用于单个项目。

  align-self:设置单元格内容垂直位置(上中下),同align-items属性的用法一致,只作用于单个项目。

  place-self:align-self和justify-self属性的合并简写,place-self: <align-self> <justify-self>,如果省略第二个值,则默认同第一个值相等。

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

  center:对齐单元格内部居中;

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

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

 

 

 

 

posted @ 2021-07-07 14:18  し7709  阅读(229)  评论(0编辑  收藏  举报