网格布局Grid

前面我们讲到了一种非常方便的布局方式flex,也提到了他是一种非常方便的一维布局解决方案,那么二维呢?我们有Grid。
作为一个二维布局,它远比flex来的强大。

什么是Grid

Grid布局,也就是我们所谓的网格布局,它可以轻松实现容器内子元素的任意位置布局(将我们的外部容器分为一个个的网格,然后在任意一个网格内放入我们想要放入的子元素),他比flex强大很多,但可惜的是,他在部分浏览器中的支持并没有flex那么普及,所以在考虑到兼容性的情况下,我们可能很少会去采用这一种布局的方式,但是这并不影响我们学习他。(对于某些项目来说,可能只需要支持某一个特定的浏览器,这个时候,Grid布局就会有很大的用武之地)和flex一样,想要把一个容器设置为grid容器也非常的简单,只需要讲他的display属性设置为grid

.box{
    display: grid | inline-grid;
}

容器的属性

网格示例

在了解容器的属性之前,我们首先需要了解以下在网格布局中非常重要的两个概念,行(row)和列(column)。在上面这幅图中,有横竖总共8条表格线,将一个容器分为了3行和3列,在我们的网格布局中,属性往往是两两出现,分别对应行和列,因此我们可以根据作用是否相同将他们进行一个分组。

  • grid-template-columns和grid-template-rows
  • grid-row-gap、grid-column-gap和grid-gap
  • grid-template-areas
  • grid-auto-flow
  • justify-items、align-items和place-items
  • justify-content、align-content和place-content
  • grid-auto-columns和grid-auto-rows
  • grid-template和grid

1.grid-template-columns和grid-template-rows

grid-template-columns:用于定义每一列的列宽
grid-template-rows:用于定义每一行的行高
对于这两个属性我们可以有很多种方式的值。

(1)直接使用px值

比如我们要实现一个上面这幅图所展示的表格我们可以这样来写(假设每一个单元格的宽高都是100px):

.box{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
}
(2)使用百分比

如果box的宽高已经固定为300px,我们还可以使用百分比来实现上面的内容

.box{
    display: grid;
    grid-template-columns: 33.3% 33.3% 33.3%;
    grid-template-rows: 33.3% 33.3% 33.3%;
}
(3)fr关键字

grid提供了一个关键字fr(片段,fraction的缩写),他代表一个比例关系,所以上面这段代码我们又可以改成这样:

.box{
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr;
}

这代表了1:1:1的关系。如果1fr 2fr 3fr,则代表了1:2:3的关系。还有一点值得注意的是,fr还可以和px值配合使用,比如grid-template-columns: 100px 1fr 1fr,代表第一列为100px,剩下两列为1:1的关系。

(4)repeat函数

我们还可以用repeat函数来写上面这个方法,他支持两个参数,第一个参数是重复的次数,第二个参数是需要重复的值。
.box{
display:grid;
grid-template-columns: repeat(3, 1fr); /* 这里的1fr当然也可以是100px或者33.3% */
grid-template-rows: repeat(3, 1fr);
}
第二个参数还可以传递某种组合,比如这样grid-template-columns: repeat(2,100px 200px),这样就会生成一共四列,其中第一第三列为100px,第二第四列为200px。

(5)auto-fill关键字

这是配合repeat函数使用的一个关键字,可以在父元素宽高不固定的时候使用。grid-template-columns: repeat(auto-fill, 100px),这段代码表示用宽度100px的列来填充容器,知道填充不下为止。

(6)auto关键字

自适应,grid-template-columns: 100px auto,比如这一段代码,代表了第一列的宽度为100px,第二列宽度自适应,会自动填充满容器的宽度。(当然也会有特殊情况比如单元格有min-width)

(7)minmax函数

产生一个长度范围,接受两个参数,分别为最小值和最大值,比如这样一段代码:grid-template-columns: 1fr minmax(100px, 1fr),代表第二列的宽度大于100px,且小于1fr。

(8)网格线的名称

我们可以给网格线来设置名称,比如这样:grid-template-columns: [c1] 100px [c2] auto [c3 end-line],我们可以看到同一根先还可以有不同的名字。

2.grid-row-gap、grid-column-gap和grid-gap

grid-row-gap:用于设置行与行之间的间距(行间距)
grid-column-gap:用于设置列与列之间的间距(列间距)
grid-gap:上面两个值的合并写法,语法grid-gap: <grid-row-gap> <grid-column-gap>,当然他也可以值传递一个参数,代表第二个值和第一个值相等。
按照最新的标准这三个属性的grid前缀可以省略,分别写成row-gapcolumn-gapgap

3.grid-template-areas

用于给单元格进行命名,可以是一个单元格代表一个区域,也可以是多个单元格代表一个区域:

.box{
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas:'a b c'
                                     'd e f'
                                     'g g g';
}

区域命名还会直接影响到网格线的名称区域名-start区域名-end

4.grid-auto-flow

可以是rowcolumnrow densecolumn dense四个值中的其中一个,表示子元素的排列规则,其中row表示先行后列,column表示先列后行。而dense表示尽可能填满,不出现空格,假设我们有a,b,c三个元素,宽度都为50%,然后我们将a,b元素上下排列,然后如果使用row排序,c元素灰出现在b元素的后面,但是如果我们使用row dense排序,c的位置就来到了a的后面,如下例:

<style>
  .box{
    display: grid;
    grid-template-columns: 100px 100px;
    grid-template-rows: 100px 100px;
  }
  .item {
    font-size: 4em;
    text-align: center;
    border: 1px solid #e5e4e9;
   }
  .item-1 {
    background-color: red;
    grid-column-start: 1;
    grid-column-end: 2;  
  }
  .item-2 {
    background-color: green;
    grid-column-start: 1;
    grid-column-end: 2; 
  }
  .item-3 {
    background-color: yellow;
  }
</style>
<div class="box">
  <div class="item item-1">a</div>
  <div class="item item-2">b</div>
  <div class="item item-3">c</div>
</div>

效果如下图:

默认:grid-auto-flow: row

现在我们给box中加上grid-auto-flow: row dense;效果变成了这样。
grid-auto-flow: row dense

5. justify-items、align-items和place-items

justify-items:设置单元格内容的水平位置(左中右)
align-items:设置单元格内容的垂直位置(上中下)
他们都可以有以下四个值:

  • stretch:拉伸,占满单元格的整个宽度(默认值)
  • start:对齐单元格的起始边缘
  • end:对齐单元格的结束边缘
  • center:单元格内部居中
.box{
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}

place-items是以上两个值的合并简写:

place-items: <align-items> <justify-items> /* 如果两个值相等则可以省略第二个值。*/

6.justify-content、align-content和place-content

主要作用于网格的内容区域没有完全填满容器的情况下。
justify-content:整个内容区域在容器里面的水平位置(左中右),
align-content:整个内容区域的垂直位置(上中下)。

.box{
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}
  • start:对齐容器的起始边框
  • end:对齐容器的结束边框
  • center:容器内部居中
  • stretch:项目大小没有指定时,拉伸占据整个网格容器
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍
  • space-between:项目与项目的间隔相等,项目与容器边框之间没有间隔
  • space-evenly:项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔
    place-content是align-content和justify-content的合并简写形式。
    place-content: <align-content> <justify-content> /* 如果两个值相等则可以省略第二个值。*/

7.grid-auto-columns和grid-auto-rows

当一些项目所在的位置超出我们现有网格的时候,可以用这两个属性来规定自动生成的网格的宽高。

8.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的合并简写形式。

项目的属性

接下来我们来看项目上可以使用哪些属性,我们依旧是分组来看:

  • grid-column-start、grid-column-end、grid-row-start和grid-row-end
  • grid-column和grid-row
  • grid-area
  • z-index
  • justify-self、align-self和place-self

1.grid-column-start、grid-column-end、grid-row-start和grid-row-end

这四个属性用于指定项目的具体位置:
grid-column-start属性:左边框所在的垂直网格线
grid-column-end属性:右边框所在的垂直网格线
grid-row-start属性:上边框所在的水平网格线
grid-row-end属性:下边框所在的水平网格线
这里我们注意看前面第一幅图中的标线,我们如果要把单元格放在第一格的位置,那就要放在水平网线1,和水平网格线2的中间。(垂直同理)
这里除了直接使用网格的数字之外,我们还可以使用网格线的名称。(就是上文定义的,这里派上了用场)
不仅如此,这里还有一个span关键字,代表左右边框之间跨越了几个网格。grid-column-start: span 2grid-column-end: span 2的效果完全一致,有了这个写法,我们可以来固定一条边,然后通过跨越几个单元格的方式来计算出另外一条边的位置。

2.grid-column和grid-row

上面四个属性的合并缩写模式,值得一提的是,这里中间要用/号进行分隔。

.item {
  grid-column: 1 / 2;
  grid-row: 1 / 2;
}
/* 等同于 */
.item {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}

值得注意的是,斜杠后面的数字是可以省略的,默认为一个网格。

3.grid-area

用于指定项目放在哪一个区域,我们可以直接这样写:

item {
    grid-area: a;
}

这样item就被放到了上面定义的a区域里面,不仅如此,他还可以看做grid-row-start、grid-column-start、grid-row-end、grid-column-end的合并简写,直接指定项目位置。

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

4.z-index

上面说了那么多的位置放置属性,那么肯定会导致位置重叠的问题,我们使用z-index来控制重叠的顺序。

5.justify-self、align-self和place-self

justify-self:设置单元格内容的水平位置(跟justify-items属性的用法一致,但只作用于单个项目)
align-self:设置单元格内容的垂直位置(跟align-items属性的用法一致,也是只作用于单个项目)

.item {
  justify-self: stretch | start | end | center;
  align-self: stretch | start | end | center;
}
  • stretch:拉伸,占满单元格的整个宽度(默认值)
  • start:对齐单元格的起始边缘
  • end:对齐单元格的结束边缘
  • center:单元格内部居中
    place-self是align-self和justify-self的合并简写形式。
    place-self: <align-self> <justify-self>  /* 如果两个值相等则可以省略第二个值。*/
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容