css最强布局方案-grid

前言

flex已经强大到足够实现很多种布局方案了,为什么又出来一个新的布局方案grid呢?
一个新的技术的出现必然是为了解决现有技术的不足之处的。
与flex的一纬布局不同,grid布局是一个二维布局系统,也就意味着它可以同时处理列和行。

通过一个示例来窥探grid的神奇之处


实现这样一个经典布局

grid有着更加语义化的属性,可以让我们像搭积木一样进行的网页布局。
grid的还有一个特性就是grid可以让我们的布局与html语义结构解耦出来,不用根据html所定义的结构顺序来渲染。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
body {
font-weight: 900;
color: #ffffff;
}

.wrapper {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 200px auto; // 定义每一列的列宽
grid-template-rows: 60px auto 60px; // 定义每一行的行高
grid-template-areas:
"header header header"
"menu content content"
"footer footer footer";
}

.header,
.footer {
background: #5b5b8e;
}

.header {
grid-area: header;
}

.footer {
grid-area: footer;
}

.menu {
background: #66cc99;
grid-area: menu;
}

.content {
background: #f9cc6e;
grid-area: content;
}


<div class="wrapper">
<div class="header">HEADER</div>
<div class="menu">MENU</div>
<div class="content">CONTENT</div>
<div class="footer">FOOTER</div>
</div>

点此看demo

grid的一些属性

grid布局相关的属性以及值远比flex多,需要好好的厘清一下。

display:grid 和 inline-grid

给父元素加上grid或者inline-grid属性即可创建一个网格容器。
一个是块级一个是行内元素,一张图就能明白。

grid-template-columns 和 grid-template-rows

同样是应用在父级的属性,grid-template-columns设置列宽,grid-template-rows设置行高,这两个属性在grid布局中尤为重要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.wrapper {
display: grid;
/* 声明了三列,宽度分别为 200px 200px 200px */
grid-template-columns: 200px 200px 200px;
/* 行与列之间的间距 */
grid-gap: 5px;
/* 声明了一行,行高为 50px */
grid-template-rows: 50px;
}

<div class="wrapper">
<div class="item one">1</div>
<div class="item two">2</div>
<div class="item three">3</div>
</div>
repeat函数

三列的话200px要写三次,如果更多呢?
我们可以使用repeat() 函数简化重复的值,该函数接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。

1
2
// 上面的css可以简写为
grid-template-columns: repeat(3, 200px);
auto-fill关键字

auto-fill:表示自动填充,让一行(或者一列)中尽可能的容纳更多的单元格。grid-template-columns: repeat(auto-fill, 200px) 表示列宽是 200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元素,代码以及效果如下图所示:

1
2
3
4
5
6
7
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
grid-gap: 5px;
/* 设置隐式创建子元素高度,隐式创建即没有具体声明的列数 */
grid-auto-rows: 50px;
}
fr关键字

grid中的长度单位,和vw,vh类似,1fr单位代表网格容器中可用空间的一等份

1
2
3
4
5
6
7
8
9
10
11
12
13
.wrapper {
display: grid;
// 表示第一个列宽设置为 200px,后面剩余的宽度分为两部分,宽度分别为剩余宽度的 1/3 和 2/3。
grid-template-columns: 200px 1fr 2fr;
grid-gap: 5px;
grid-template-rows: 50px;
}

<div class="wrapper">
<div class="item one">1</div>
<div class="item two">2</div>
<div class="item three">3</div>
</div>
minmax()函数

minmax()函数包含两个参数,最小值 和 最大值,表示长度就在这个范围之中都可以应用到网格项目中。概念有点晦涩难懂蛤,那就直接上代码。

1
2
3
4
5
6
7
.wrapper {
display: grid;
// 第三个列宽最少也是要200px,但是最大不能大于第一第二列宽的两倍
grid-template-columns: 1fr 1fr minmax(200px, 2fr);
grid-gap: 5px;
grid-template-rows: 50px;
}
auto 关键字

flex:1一样的效果,由浏览器决定长度。

1
2
3
4
5
6
.wrapper {
display: grid;
// 表示第一第三列为200px,中间由浏览器决定长度
grid-template-columns: 200px auto 200px;
grid-template-rows: 50px;
}

grid-row-gap 属性、grid-column-gap 属性以及 grid-gap 属性

grid-row-gap属性、grid-column-gap属性分别设置行间距和列间距。grid-gap 属性是两者的简写形式。

1
2
3
4
5
grid-row-gap: 10px;
grid-column-gap: 20px;

// 可以简写为:
grid-gap: 10px 20px;

grid-template-areas 属性

一个布局样式,grid-template-areas 属性用于定义区域,一个区域由一个或者多个单元格组成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#page {
display: grid;
width: 100%;
height: 100%;
// 因为是两列,所有"head head"不能简写为"head"
grid-template-areas: "head head" "nav main" "nav foot";
// 区域划分 当前为 三行 两列
grid-template-rows: 50px 1fr 30px;
// 各区域 宽高设置
grid-template-columns: 150px 1fr;
}
#page>header {
grid-area: head;
// 指定当前元素所在的区域位置, 从grid-template-areas选取值
background-color: #8ca0ff;
}

#page>nav {
grid-area: nav;
background-color: #ffa08c;
}

#page>main {
grid-area: main;
background-color: #ffff64;
}

#page>footer {
grid-area: foot;
background-color: #8cffa0;
}
<section id="page">
<header>Header</header>
<nav>Navigation</nav>
<main>Main area</main>
<footer>Footer</footer>
</section>

演示地址

grid-auto-flow 属性

grid-auto-flow 属性控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。默认的放置顺序是”先行后列”,即先填满第一行,再开始放入第二行。

理解起来复杂,直接戳这边看演示demo

justify-items 属性、align-items 属性以及 place-items 属性

justify-items 属性设置单元格内容的水平位置(左中右),align-items 属性设置单元格的垂直位置(上中下),place-items 是align-items和justify-items的简写属性。

同样戳这边看演示demo

justify-content 属性、align-content 属性以及 place-content 属性

*-content 属性是整个内容区域在容器里面的位置,效果同flex不再过多介绍。

grid-auto-columns 属性和 grid-auto-rows 属性

grid-auto-columnsgrid-auto-rows是作用于隐式网格的两个属性。

先来看看隐式和显式网格的概念,显式网格包含了你在 grid-template-columns 和 grid-template-rows 属性中定义的行和列。如果你在网格定义之外又放了一些东西,或者因为内容的数量而需要的更多网格轨道的时候,网格将会在隐式网格中创建行和列。

如果不给隐式网格设置grid-auto-columnsgrid-auto-rows属性,则浏览器会根据单元格内容的大小,自行决定网格的列宽和行高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.wrapper {
display: grid;
// 只设置了两行,但实际的数量会超出两行,超出的行高会以grid-auto-rows和grid-auto-columns属性值为准
grid-template-columns: 100px 100px;
grid-template-rows: 100px 100px;
grid-gap: 50px;
grid-auto-columns: 50px;
grid-auto-rows: 50px;
}

<div class="wrapper">
<div class="item one">1</div>
<div class="item two">2</div>
<div class="item three">3</div>
<div class="item four">3</div>
<div class="item five">3</div>
<div class="item six">3</div>
</div>

grid子元素的一些属性

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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.wrapper {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
background-color: #cccccc;
}

.two {
grid-column-start: 2;
grid-column-end: 4;
// 上面两个属性可以写为grid-column-start: span 2; 或者 grid-column-end: span 2;
}

<div class="wrapper">
<div class="item one">1</div>
<div class="item two">2</div>
<div class="item three">3</div>
<div class="item four">4</div>
<div class="item five">5</div>
</div>

grid-column-start的一个demo

1
2
3
4
5
6
7
8
9
10
.three {
grid-column-start: 1;
grid-column-end: 3;
}

<div class="wrapper">
<div class="item one">1</div>
<div class="item two">2</div>
<div class="item three">3</div>
</div>

grid-row-start的一个demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.wrapper {
display: grid;
grid-template-columns: repeat(2, 100px);
grid-template-rows: repeat(2, 100px);
background-color: #cccccc;
margin-left: 100px;
}

.one {
grid-row-start: 1;
grid-row-end: 3;
// 上面两个属性同样可以简写为grid-row-start: span 2;或者grid-row-end: span 2;
}

<div class="wrapper">
<div class="item one">1</div>
<div class="item two">2</div>
<div class="item three">3</div>
</div>

justify-self 、align-self 以及 place-self

justify-self属性设置单元格内容的水平位置(左中右),跟 justify-items 属性的用法完全一致,但只作用于单个项目
align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目
place-self则是align-selfjustify-self的简写

点此处看演示demo

参考资料

最强大的 CSS 布局 —— Grid 布局
CSS Grid 网格布局教程


css最强布局方案-grid
https://xypecho.github.io/2020/08/26/css最强布局方案-grid/
作者
很青的青蛙
发布于
2020年8月26日
许可协议