前言
在你确认css网格布局真的很简单之前,你肯定要知道css的那些基础知识,比如选择器,属性等,一言概之,你得知道css怎么用。
开篇
css属性大多属性名就已经说明它本身是什么作用了,而你要记住的只不过是相应的值会有什么效果。然而,英文意思翻译过来有时会对理解其作用造成干扰,因而这里列举一些可能会如此的词出来,解释其含义。当你困惑时可回来印证。
- “wrap”:包,缠绕
比如:这个词出现在white-space:wrap | nowrap;
粗浅的理解:当文本内容超过容器盒子时,要不要换行。你可能困惑:包和缠绕怎么也跟换行联系不到一起啊。这是因为wrap的主语是“容器盒子”,即容器盒子要不要包住文本。而换行的主语是文本,容器盒子如果要求包住,那文本只能为了达到要求而进行换行。下面将会多次出现该词。
- “content”:内容
剑桥词典:“the articles or parts contained in a magazine or book, with the number of the page they begin on”--英文解释起来反而make sense(实用、有实效)。也就是说:这个内容是复数的,有多个的。了解过Flex布局的,最多见的还是justify-content
和align-content
。这里你先记住一个重点就够了:复数,也就是多个的。
- “item”:项目
剑桥词典:“one of several subjects to be considered”。这里我想强调的点是这个词是单数的,这里与content对比下。而你常见的应该是align-items
(多了个“s”)。
- “justify”和“align”
这两个词比较难以“make sense”,你且直接记住,justify代表主轴,align代表交叉轴(副轴)。
正文:网格布局挺简单呐!
首先,要形成网格布局,需要一个容器盒子,然后里面就是一个一个的格子,格子之间还有间隙。因此,相关的属性可以分为两组:设置在容器盒子的属性,设置在格子的属性。
1. 总纲领
1.1 设置在容器盒子的属性。
display: grid | inline-grid
一个网格的诞生
😊 | 行列 | 间隔 | 伸缩 | 扎堆 |
---|---|---|---|---|
列 | grid-template-columns | grid-column-gap | justify-items | justify-content |
行 | grid-template-rows | grid-row-gap | align-items | align-content |
简写 | grid-template | grid-gap | place-items | place-content |
😁 | 备胎 | 流 |
---|---|---|
列 | grid-auto-rows | grid-auto-flow |
行 | grid-auto-columns |
1.2 设置在格子的属性。
😆 | 定位开始 | 定位结束 | 简写 |
---|---|---|---|
列 | grid-column-start | grid-column-end | grid-column |
行 | grid-row-start | grid-row-end | grid-row |
😘 | 特立独行 |
---|---|
列 | align-self |
行 | justify-self |
简写 | place-self |
1.3 父子组合
💕 | 父盒子 | 子格子 |
---|---|---|
属性 | grid-template-areas | grid-area |
你先别被吓到,上面看起来很多的属性,其实很多是CP 或者是简写,总之你很容易记住。
2. 各个击破。
先从容器盒子的属性开始。display: grid | inline-grid;
就不用说了,一个网格布局诞生的前提。
2.1 行列
grid-template-columns
、grid-template-rows
、grid-template
。 这一组挺好理解,grid-template-columns
、grid-template-rows
列和行分别多少,grid-template
将行列简写。
上代码
<div class="container">
<h1>Grid Layout</h1>
<div class="grid-container">
<div class="item1">item1</div>
<div class="item2">item2</div>
<div class="item3">item3</div>
<div class="item4">item4</div>
<div class="item5">item5</div>
<div class="item6">item6</div>
<div class="item7">item7</div>
<div class="item8">item8</div>
<div class="item9">item9</div>
</div>
</div>
.grid-container {
display: grid;
grid-template-rows: 33.33% 33.33% 33.33%;
grid-template-columns: 33.33% 33.33% 33.33%;
}
效果
拓展:
grid-template-columns: 33.33% 33.33% 33.33%;
可以换一个写法:grid-template-columns: repeat(3, 33.33%);
多简单!第一个参数代表重复的次数,而第二个参数就是被重复的对象。grid-template-rows
同理。fr
是 fraction的缩写,表示“片段、分数”。你直接理解为一个占比的单位。grid-template-columns: 33.33% 33.33% 33.33%;
可以写成grid-template-columns: 1fr 1fr 1fr;
或者template-columns: repeat(3, 1fr)
。(除了百分比,fr,值还可以是具体的像素距离如100px
、auto
、minmax()
…自己试试)。repeat(arg1, model)
的第一个参数还可以是auto-fill
,表示”重复多少次看情况,塞满就行”。
2.2 间隔
grid-column-gap
、grid-row-gap
、grid-gap
。这一组也很好理解。gap表示间隔,前两个的值是20px等表示距离的值。
上代码
.grid-container {
display: grid;
grid-template-rows: 33.33% 33.33% 33.33%;
grid-template-columns: 33.33% 33.33% 33.33%;
grid-column-gap: 20px;
grid-row-gap: 20px;
}
效果
拓展:
- 我们加上gap之后,发现内容超出了盒子,也间接知道了:gap不包含在用百分比分割的格子里面,长度自己算自己的。
grid-gap: <grid-row-gap> <grid-column-gap>;
简写
2.3 伸缩
justify-items
、align-items
、place-items
。这一组很好说,前面解释过item,它是单数,然后加上“s”. 我之所以强调这一点,是因为如下效果。
上代码
.grid-container {
display: grid;
grid-template-rows: 33.33% 33.33% 33.33%;
grid-template-columns: 33.33% 33.33% 33.33%;
grid-column-gap: 20px;
grid-row-gap: 20px;
justify-items: center;
align-items: center;
}
效果
分析助记:首先我们要知道其有四个值:stretch | start | end | center;
而其效果是:
- 对一个格子里面的布局进行拉伸收缩,且不管如何都不会超出原来的格子范围,这对应item单数;
- 根据item前面是justify或align,控制主轴或副轴,让每一个都重复单个格子的伸缩,这都应了item后面的“s”。
place-items: <align-items> / <justify-items>;
简写。
2.4 扎堆
justify-content
、align-content
、place-content
。这一组与前面2.3讨论的对应,也简单。首先justify-content
、align-content
都有七个值start | end | center | stretch | space-around | space-between | space-evenly;
对应有什么效果我只写一个,其他你自己玩一下就懂了,我后面的分析才是重点。
上代码
.grid-container {
display: grid;
grid-template-rows: 25% 25% 25%;
grid-template-columns: 25% 25% 25%;
grid-column-gap: 20px;
grid-row-gap: 20px;
justify-content: start;
align-content: end;
}
效果
分析助记:还记得前面说过吗,content是复数,与2.3的item对立,所以其效果也是“人如其名”,它控制的是主轴或副轴方向的多个格子的拉伸收缩,注意这里要把多个格子看成一个整体。(PS:格子+间隔gap的宽度要<容器宽度才有效果)
place-content: <align-content> / <justify-content>;
依旧简写。
2.5 备胎
grid-auto-columns
、grid-auto-rows
。这组属性,如果你理解了前面grid-template-columns/rows
, 那么这组属性也很好理解。你理解为他们的“备胎”就行,也就是说,当某一个格子被自己的属性“定位”到容器盒子之外的地方时,你提前设定的“备胎”行列就发挥作用了。
上代码
.grid-container {
display: grid;
grid-template-rows: 25% 25% 25%;
grid-template-columns: 25% 25% 25%;
grid-auto-columns: 10%;
}
.item3 {
grid-column-start:4;
}
效果
分析助记:其中控制格子item3定位到容器格子外后面讲解,你只要关心设定的“备胎”列宽度为10%,所以item3“出轨”的列就只要10%。grid-auto-rows
同理。
这两个倒是没有简写。
2.6 流
grid-auto-flow
。这个属性的重点字眼是flow,即“流”。有值:
grid-auto-flow: row | column | row dense | column dense
。前两个好理解,就是流的方向,那后面又分别加了dense,意思“紧密,使紧密”。可否理解为流中的排列更加紧密?
且看代码
.grid-container {
display: grid;
grid-template-rows: 25% 25% 25%;
grid-template-columns: 25% 25% 25%;
grid-auto-rows: 25%;
grid-auto-flow: row;
}
.item1 {
grid-column-start:1;
grid-column-end:3;
}
.item2 {
grid-column-start:1;
grid-column-end:3;
}
效果
上面代码让第一个格子和第二个格子各占据2各格子的宽度(后面讲解),你关注默认的流动。
加了dense呢?
.grid-container {
grid-auto-flow: row dense;
}
效果
分析助记:蛮简单,就是流动方向控制,没有dense就“松”的“流”动,会留下空格;加dense会填满多余空格。
到这里,其实你已经把容器盒子的grid属性看完了:说白了就六个“东西”:
- 控制几行几列的
grid-template-columns/rows
。 - -控制格子间隔的
grid-row/column-gap
。 - 单个格子里面的拉伸收缩方式
align/justify-items
。 - 主轴或副轴方向的多个格子的整体的拉伸收缩方式
align/justify-content
。这样看来,是不是就清晰明了啦。 - 备胎
grid-auto-columns/rows
。 - 流动方向及松紧
grid-auto-flow
。So easy!
grid
以上所有属性简写,这里不建议初学者用,等有css优化需求再尝试用。
接下来说一下单个格子自己的属性,就更加简单呐。
2.7 定位
grid-column-start
、grid-column-end
、grid-row-start
、grid-row-end
、grid-column
、grid-row
这一组就很直接了,start和end,开始和结束,又是应用在格子上面,那就很“make sense”了,意思就是格子开始和结束的位置,接着其值是数字,如果我们这样描述一个格子:格子从第1个*开始,到第3个*结束。那盒子容器里面有什么能够作为*的代表呢?不就是网格线么?至于主轴和副轴还有简写就无须赘述啦~
再上代码
.grid-container {
display: grid;
grid-template-rows: 25% 25% 25%;
grid-template-columns: 25% 25% 25%;
grid-auto-rows: 25%;
}
.item1 {
grid-column-start:1;
grid-column-end:3;
}
.item2 {
grid-column-start:1;
grid-column-end:3;
}
效果
2.8 特立独行
justify-self
、align-self
、place-self
。这是格子的最后一组属性啦。self单词意思大家都懂:自己。首先自己是单数的,其次,自己-自己说了算。前面我们提到的容器盒子align-items
,他就是对格子发出拉伸收缩的指令,且带“s”,对一群格子施令。而总有那么一两个不听,想自己说了算。至于主轴和副轴还有简写就无须赘述啦!
看代码
.grid-container {
display: grid;
grid-template-rows: 25% 25% 25%;
grid-template-columns: 25% 25% 25%;
justify-items: center;
}
.item5 {
justify-self: start;
}
效果
到这里,格子上单独自己设置的属性就没啦,也就两组:第一组就是给格子定位的start 和end,以网格线为参照;第二组就是特立独行的self。So easy, right ?
3. 父子CP
还有最后一组,这一组与上面的不同,不是单独设置就能生效的,要容器盒子和格子配合才有效果。但是,简单得有点尴尬。CP(组合使用)grid-template-areas
(父)、grid-area
(子)。打个比方:诸侯分封,土地各自属于哪个诸侯。
上代码
<div class="container">
<h1>Grid Layout</h1>
<div class="grid-container">
<div class="item1">item1</div>
<div class="item2">item2</div>
<div class="item3">item3</div>
<div class="item4">item4</div>
</div>
</div>
.grid-container {
display: grid;
grid-template-rows: 25% 25% 25%;
grid-template-columns: 25% 25% 25%;
grid-template-areas:
"item1 item1 item2"
"item3 item3 item2"
"item4 item4 item4";
}
.item1 {
grid-area: item1
}
.item2 {
grid-area: item2
}
.item3 {
grid-area: item3
}
.item4 {
grid-area: item4
}
效果图
结语
其实我前面一直强调简单,原因有三:其一,网格布局各个属性的设置很全面也很好理解,“难”的只是多和杂;其二,我只有强调简单才能减少你阅读时的枯燥和增加你的自信;其三,本文是对参考博文的的总结,具体的细节还需要你用心去实践和体会,毕竟修行靠个人。
参考文献
1. CSS Grid 网格布局教程,阮一峰
(条理清晰,简单易懂)
2. 写给自己看的display: grid布局教程,张鑫旭
(深入分析,互动性强)