什么是 Grid

  • Grid 是一种 CSS 布局方案
  • 将浏览器划分为一个个网格并可以任意组合
  • Flex 和 Grid 看似相似,但内在相差很大
    • Flex 是轴线布局,只能指定 Item 处于轴线某个位置
    • Grid 是网格布局,将容器划分为,产生单元格,并指定 Item 处于某个单元格中

基本概念

  • row 行
  • column 列
  • grid line 网格线
  • cell 单元格
  • 将容器设置为display: grid后,容器内子元素的floatdiaplay: inline-blockdisplay: table-cellvertical-aligncolumn-*等设置都会失效

这个游戏能帮你更好的学习 grid

容器属性

grid-template-columns 和 grid-template-rows

<div class="container">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>9</div>
</div>
.container{
    display: grid;
    grid-template-columns: 100px 100px 100px; /*将元素分为三列,,每一列的宽度是100px*/
    grid-template-rows: 100px 100px 100px; /*将元素分为三行,每一行的高度是100px*/
    /*
    产生一个三行三列的网格,列宽和行高都是100px
    除了使用px单位,也可以使用百分比
    */
}
.container > div {
    border: 1px solid blue;
    margin: 5px;
}

repeat()

.container{
    display: grid;
    width: 300px;
    height: 300px;
    grid-template-columns: repeat(3, 33.33%);
    grid-template-rows: repeat(3, 33.33%);
}

repeat()的第一个参数表示重复的次数,第二个参数表示重复的值,不过它并不是只能接受两个参数

.container{
    display: grid;
    grid-template-columns: repeat(3, 20px 50px 30px);
}

以上代码定义了9列,1、4、7列的宽为20px;2、5、8列的宽为50px;3、6、9列的宽为30px

auto-fill

当单元格的大小是固定的,但容器大小不确定,此时我们希望每一行、每一列尽量容纳多的单元格,这是可以使用auto-fill表示自动填充

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

fr

fr能表示子元素大小的比例关系

.container {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
}

以上代码表示第二列的宽是第一列和第三列的两倍,使用fr时也可以结合绝对单位:grid-template-columns: 150px 2fr 1fr;

minmax()

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

以上代码表示第三列的宽最小值为100px,最大值为第一列和第二列的两倍

auto

auto表示浏览器自己决定长度

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

指定网格线名称

 .container{
     display: grid;
     grid-template-columns: [c1] 100px [c2] 100px [c3] 100px [c4];
     grid-template-rows: [r1] 100px [r2] 100px [r3] 100px [r4];
}

网格布局允许同一根线有多个名字,比如[start-line r1]

grid-row-gap、grid-column-gap、grid-gap

grid-row-gap设置行与行之间的间隔,grid-column-gap设置列与列之间的间隔,gird-gap则是两个属性的缩写

.container{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-column-gap: 5px;
    grid-row-gap: 5px;
    /* 
    grid-gap: 5px 5px; 
    grid-gap: row-gap column-gap;
    如果忽略第二个值,那么浏览器会默认第二个值与第一个值相等
    */
}

grid-auto-flow

grid的放置顺序为先行后列,先填满第一行,再开始填充第二行,grid-auto-flow可以改变这个顺序。

.container{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-auto-flow: column; /* 先列后行,默认值是 row */
}

grid-auto-flow还有另外两个值:row-densecloumn-dense,表示让子元素尽可能密集排布,哪怕转换元素的顺序。

justify-items、align-items、place-items

justify-items用于设置单元格内容的水平位置(左中右),align-items用于设置单元格内容的垂直位置(左中右)

.container {
    justify-items: start | end | center | stretch;
    align-items: start | end | center | stretch;
}

place-items以上两个属性的缩写

.contianer{
    place-items: <align-items> <justify-items>;
}
/*如果忽略第一个值,浏览器默认第二个值等于第一个值*/

justify-content、align-content、place-content

作用跟上面三个属性相似,不过*-content表示的是容器内整个内容区域的位置,*-items表示子元素在单元格中的位置

.container {
    justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
    align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}
/* space-evenly 表示子元素之间的间距相等,子元素与容器边框之间的间距也相等 */

子元素属性

grid-column-start、grid-column-end、grid-row-start、grid-start-end、grid-column、grid-start

以上属性可以指定子元素在容器内占据的单元格位置

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

.item{
    grid-column-start: 1; 
    grid-column-end: 3
}

以上代码指定了item占据了2个单元格,以第一根垂直网格线为起点,以第三根垂直网格线为终点,不仅可以写第几根网格线,也还可以写网格线名称。

也可以使用span来表示跨越多少个网格

 .item{
     grid-column-start: 1;
     grid-column-end: span 3;
}
/*从第一根垂直网格线开始,跨越三个单元格*/

grid-columngrid-row则是对应属性的缩写

.item {
    grid-column: <start-line> / <end-line>;
    grid-row: <start-line> / <end-line>;
}
/* 同样可以使用 span */

justify-self、align-self、place-self

justify-itemsalign-itemsspace-items用法相同,不过*-self仅作用与单个子元素

.item {
    justify-self: start | end | center | stretch;
    align-self: start | end | center | stretch;
}

place-items是两个属性的缩写

.item{
    place-self: <align-self> <justify-self>;
}

区域相关的内容

grid-template-areas

网格布局可以指定区域,一个区域又单个或多个单元格组成,grid-template-areas用于自定义区域

.container{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: repeat(3 100px);
    grid-template-areas: 'a b c'
        			    'd e f'
        				'g h i'
}

也可以将多个单元格合并为一个区域

.container{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: repeat(3 100px);
    grid-template-areas: 'a a a'
        			    'b b b'
        				'c c c';
}
/*
如果某个区域不需要利用,则可以用"."来表示

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

grid-area

用于指定子元素放在哪一个区域

.item {
    grid-area: e;
}

grid-area属性还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式,直接指定项目的位置。

.item {
  grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}