优秀的编程知识分享平台

网站首页 > 技术文章 正文

5分钟带你学会 grid 栅格布局,建议收藏

nanyue 2025-01-07 14:46:39 技术文章 4 ℃

flex 布局在项目中是必不可少的,但 grid 是一个比 flex 布局还要强大的布局方式。所以今天就来重学一遍 grid 栅格布局。

一、grid 基本概念

flex 可以看做一维布局,只针对的是水平方向或者垂直方向。grid 则将容器划分成行和列,产生单元格,然后指定项目的单元格,可以看做是一个二维布局。所以 grid 布局要比 flex 布局更强大。

1.1、容器和项目

容器 [container]:采用网格布局的区域,就叫做容器。

项目 [ item ]:容器内部采用网格定位的子元素,叫做项目。

注意:最外层包裹的就是容器,项目只能是容器的顶层子元素,不包含项目的子元素,grid 布局只对项目生效。

1.2、行和列

二维布局就像表格一样,容器里面的水平区域称为行[ row ]。容器的垂直方向区域称为列[ column ]。

1.3、单元格

单元格[ cell ]:行和列的交叉区域就称为单元格。

单元格的数量是由行和列决定的。如 n 行 m 列,将会产生 n*m 个单元格。

1.4、网格线

网格线:划分单元格的线,就叫做网格线。水平网格线划分出行,垂直网格线划分出列。

栅格布局的基本概念以及分布结构如图:

二、容器属性

grid 布局的属性分为两类,一类定义在容器上面,称为容器属性。另外一个定义在项目上,所以叫做项目属性。所以该部分所讲的属性都是定义在容器上面的。

2.1、display

div{
 display:grid
}

用来指定容器的布局方式,采用网格布局。

默认情况下,容器都是块级元素,也可以设计成行内元素。使用:

display : inline-grid ;

注意点:使用栅格布局之后,容器子元素的 float、inline-block、table-cell、vitical-align 属性都将失效。

2.2、grid-template-columns、grid-template-rows

gird-template-columns 用来设置容器要被划分为几列,被划分列的宽度设置。

grid-template-rows 用来设置容器被划分成几行,并设置每行的高度。

使用示例:

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

上面代码设置三列,宽度分别为:200px、100px 和 50px。设置了两行,高度都设置成50px 。

生成一个简单的布局如图:

我们设置了两行,前两行的高度都是 50px ,超出两行的未设置高度,会自动挤满剩余的容器。

除了上述的固定大小之外,也可以使用百分比。

1.repeat()

我们上边设置两个行的高度都为 50px ,我们如果设置100行都为 50px 时,重复写 100 个值非常麻烦,还容易出错,所以引入了 repeat 函数。

repeat() 函数可以简化重复值,使用语法为:

grid-template-row: repeat( n , size )

语法中,两个参数,第一个参数 n ,表示重复的次数,第二个参数表示需要重复的值。第二个参数:可以是单个值也可以是多个值。所以:

grid-template-rows:50px 50px;
// 可改写为
grid-template-rows: repeat( 2, 50px );

重复多个值:

grid-template-rows: repeat( 2, 100px 80px 50px)

相当于把后边的 100px 80px 50px 重复 2 次,就是分成了 6 列。

2.auto-fill

auto-fill 表示自动填充。

有时单元格大小是固定的,但是容器大小是不确定的,使用 auto-fill 设置能够尽可能多的单元格,自动地填充容器。

使用示例:

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

上述实例,表示所有的列宽度大小都为 150px ,自动填充,直到容器不能放置更多的列,剩余的列会自动排列到下一行。

3.fr 关键字

为了方便表示比例关系,网格布局提供了 fr 关键字。

使用示例:

grid-template-columns: 1fr 200px;

上述代码表示:设置两列,第二列固定宽度为 200px,第一列自动填充容器剩余宽度。

grid-template-columns: 1fr 2fr;

上边这个代码没有具体的数值,两个都是 fr,表示两列的宽度为 1:2,填满容器。

实现效果如图:

4.minmax()

minmax() 函数会产生一个长度范围,表示长度的一个最大和最小值,使用语法为:

minmax( min, max )

可以接受两个参数,第一个参数表示最小值,第二个参数表示最大值。

使用示例:

grid-template-columns: 1fr 2fr minmax( 100px, 150px )

上述代码表示:容器内设置三列,第一列与第二列是 1:2,第三列大小介于 100-150px之间。

5.auto

auto 关键字,自动分配大小,由浏览器自己决定。

使用示例:

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

表示第一和第三列大小分别为 100 和 50 。第二列 auto 会自动填充容器剩余的宽度。除非单元格设置了 min-width ,而且这个值大于最大宽度。

6.网格线

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

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

上述代码指定网格是 3*3 的布局,因此会有4根垂直网格线和4根水平网格线。

表示垂直方向的四根线依次为:c1、c2、c3、c4。

表示水平方向的四根线依次为:r1、r2、r3、r4。

2.3、row-gap、column-gap、gap

row-gap:设置行间距的。它替代了之前的 grid-row-gap 。

column-gap:设置列之间的间距,它替代了之前 grid-column-gap。

使用示例:

row-gap:20px;
column-gap:20px;

运行结果为:

gap 属性是用来合并上述 column-gap 和 row-gap 两个属性。它替代了之前的 grid-gap。

上述两个代码可以合并成:

gap: 20px 20px;

第一个值表示行间距,第二个表示列间距。如果两个值相同,则可以合并写成一个。如:

gap: 20px;

2.4、grid-template-areas

网格布局允许指定区域,一个区域可以是一个单元,也可以是很多个单元格组合而成。grid-template-areas 属性用于定义区域。

使用示例:

grid-template-areas:'a b c' 'd e f' 'g'

将每个单元格设为一个区域。分别对应下边这七个单元。

将多个单元格作为一个区域,使用示例:

grid-template-areas:'a a a' 'b b b' 'c'

将上边的七个单元格划分为 3 个区域,分别为: a b c

2.5、grid-auto-flow

用于定义格子的排列顺序,默认的放置顺序为先行后列,即填满第一行,再开始放入第二行。

grid-auto-flow 有两个属性值:

    • row:先行后列,也是默认值。
    • column:先列后行。

排列方式直接影响最终的布局。如图所示:

还有一个 dense 修饰,设置的值为:row dense 和 column dense 。

在设置

grid-auto-flow: row;

页面会产生这样的布局:

第一个单元格后面位置是空的,这是因为 3 号项目默认排列在 2 号项目之后,所以导致上面空了。

如果使用 row dense ,表示 先行后列,并且尽可能紧密填满,尽量不出现空白。

grid-auto-flow: row dense;

提高了容器的空间利用率。项目排列为:

2.6、justify-items、align-items

justify-item:设置单元格内容在水平方向的对齐方式。

align-item:设置单元格内容在垂直方向的对齐方式。

使用语法:

justify-items: start | end | center | stretch
align-items: start | end | center | stretch

语法内对齐方式及意义:

  • statr:对齐单元的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部对齐。
  • stretch:拉伸,占满单元格整个宽度或高度。也是默认值。

示例:

justify-items: start;

运行结果如图:

justify-items: end;

2.7、justify-content、align-content、place-content

justify-content 属性设置整个内容区域在容器里面的水平位置。

align-content 属性是整个内容区域在垂直方向的位置。

使用语法:

 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:项目与项目的间隔相等,项目与容器之间也是同样长度的间隔。

使用示例:

justify-content: space-around

运行结果为:

justify-content: space-between
justify-content: space-evenly

place-content 用于合并 align-content 属性和 justify-content 属性。使用语法为:

place-content: <align-content> <justify-content>

如果只使用了一直值,默认两个属性值是相同的。

2.8、grid-auto-rows、grid-auto-columns

有些项目的指定位置,在现有的网格外部,比如:

.container{
 height:300px;
 width:400px;
 display:grid;
 grid-template-columns: 100px 80px 50px;
 grid-template-rows:50px 50px; 
 }

设置了三列两行,但是写了 7 个div,这时浏览器就会自动创建多余网格,所以第七个网格就叫做多余的网格,如上图。

grid-auto-columns :用来设置浏览器自动创建的多余网格的列宽。

grid-auto-rows:用来设置浏览器自动创建的多余网格的行高。

如果不指定大小时,浏览器会根据单元格内容,决定多余网格的列宽和行高,默认挤满容器剩余空间。

给上述实例新增

grid-auto-rows:80px;

运行结果如图:

三、项目属性

定义在项目上的属性,称之为项目属性。下列这些属性都是定义在项目上的。

3.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:下边框所在的水平网格线。

使用示例:

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

指定 1 号项目,左边框是1号线,右边框是3号线。上边框是1号线,下边框 3 号线。所以 1 号项目,最终占据两行两列。

运行如图:

有时候横跨列数或者行数太多时,数网格线就有点麻烦,容易犯错误。我们也可以使用 span 设置横跨的个数。

span 设置横跨的行数或列数。与 table 中的 colspan 、rowspan 相似,便于记忆。使用的时候与上述的四个属性相结合使用。

.item-1{
  grid-column-start:span 2;
	grid-row-start:span 2;
}

与上述效果相同。

注意:如果产生了项目重叠,则使用 z-index 属性指定项目的重叠顺序。

3.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>

使用示例:

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

可以简写为:

.item-1{
 grid-column:1/3;
 grid-row:1/3
}

3.3、grid-area

grid-area:指定项目放入哪个区域。

使用方式1:与容器属性中的 grid-template-areas 配合使用。使用语法:

.container{
 grid-template-areas:  'a a a' 'b b b' 'c' 
}
.item-1{
 grid-area: b
}

grid-area 后的属性值根据上边定义的区域名而来。

使用方式2:通过指定行线和列线的开始和结束位置来指定区域。使用语法:

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

3.4、justify-self、align-self、place-self

justify-self:属性设置单元格内容的水平位置(左中右),与 justify-items 属性用法一致,区别在于 justify-items 用于容器,而 justify-self 用于单个项目。使用语法:

justify-self: start | end | center | stretch

align-self:设置单元格的内容垂直方向(上中下),跟 align-items 属性用法一致,区别在于 align-items 用于容器,slign-self 用于单个项目。

align-self: start | end | center | stretch

属性值以及意义与上述一致,此处不再解释。

place-self:用于合并 align-self 属性和 justify-self 属性,简写水平和垂直方向的对齐方式。使用语法:

place-self: <align-self> <justify-self>;

如果省略第二个值,则默认两个值相等。

四、实现两栏布局

两栏布局是最常见的一种方式,面试中也经常会遇到问你两栏布局都有哪些方案?

<style>
 body{
  background-color: #EBEBEB;
  margin:0;font-size:30px; 
  text-align:center;
  line-height:100vh
 }
 .section{
  height:100vh;
  display:grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows:auto; 
  gap:10px 10px;
 }
 .aside{
  background:pink;
  grid-column:1/2;
  grid-row:1/2;
 }
 .main{
  background:lightblue;
  grid-column:2/3;
  grid-row:1/2;
 }
</style>
 
<div class="section">
 <aside class="aside">aside</aside>
 <main class="main">main</main> 
</div>

运行结果:

最近发表
标签列表