倘若讲Flexbox是那所谓的“一维战神”,其专长在于一排排地排列,那么Grid便是“二维霸主”,它能够同时对行与列进行操控。于今日,我们就要开启这一场“布局围棋”,运用网格思想将网页进行彻底地重构,使得复杂的布局转变成像填格子那般简易。前言。
回忆一下小时候玩耍过的方格本,好不好?它呈现一行又一行排列,一列跟一列布局,十分依规守距。Grid布局已然在怎样的情形下,将这般的“方格本”思维引入到CSS之中呢?你能够于页面之上,精准地描绘出任意行数、任意列数,接着还能把元素放置进去,想要放置在哪一种格子里面,就放到与之对应的具体位置,不但如此呀 , 甚至能够去合并单元格,这般的操作模式——恰似Excel表格,然而相比Excel表格而言,灵活性简直优越了一万倍呢!
适用于页面整体架构、卡片墙以及仪表盘等等这类需要同时对行与列进行控制的情景的CSS布局之中,Grid堪称终极武器。要是把Flexbox比作擅长单兵作战的特种兵,那么Grid就如同能够调动诸多要素的指挥官。
一、Grid的核心概念:容器与项目,行与列
如同Flexbox那般,Grid同样是作用于父容器以及直接子项目。只需在父元素之上设置display: grid或者display: inline-grid,于是你便开启了一个网格世界。
.container {
display: grid;
}
默认为情况下,网格仅有一列,行高是由内容来决定的。要切实“画”出网格,你得运用grid - template - rows以及grid - template - columns去定义行和列。
二、定义网格:画出你的棋盘1. 固定行高和列宽
你可以用各种单位定义行列的尺寸,比如像素、百分比、em等。
.container {
display: grid;
grid-template-columns: 200px 200px 200px; /* 三列,每列200px */
grid-template-rows: 100px 150px; /* 两行,第一行100px,第二行150px */
}
这般一来,你便绘制出了一个网格,此网格有三列,两排,合计达六个格子。项目会依照顺序,自行去填充每一个格子,恰似在表格之中,从左边朝着右边,自上方向下方去填入数据那般。
2. fr单位:分蛋糕神器
Grid引入了fr单位,fr单位是fraction的缩写,它体现的是剩余空间的比例分配,这种方式相比Flexbox的flex - grow要更加直观。
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 三列,中间占两份,两边各占一份 */
}
倘若父容器宽度为1200px,那么第一列所占宽度是300px,第二列是600px,第三列是300px。fr能够跟固定单位混合运用,臂如200px 1fr 2fr,浏览器会率先分配200px,剩余的按照比例进行分配。
3. repeat() 函数:偷懒必备
要是你打算去定义数目众多的等宽列,仅仅依靠手动书写的话,会让人觉得非常累,这个时候repeat()函数就能够前来救场了。
.container {
grid-template-columns: repeat(3, 1fr); /* 三列等宽,相当于 1fr 1fr 1fr */
grid-template-rows: repeat(4, 100px); /* 四行,每行100px */
}
repeat()能够组合不一样的模式,举例来说,repeat(2, 100px 1fr)意味着重复两次“100px 1fr”这个序列,最终得出四列,分别是:100px、1fr、100px、1fr。
4. minmax():给尺寸一个范围
有的时候,我们期望列宽能够在一定的范围之内进行弹性变化,举例来说,最小是200px,最大是自适应,minmax()能够搞定。
.container {
grid-template-columns: minmax(200px, 1fr) 2fr; /* 第一列最小200px,可以放大到1fr,第二列固定2fr */
}
5. auto-fill 与 auto-fit:响应式利器
当列数没办法确定的时候,能够通过auto-fill,或者auto-fit,去配合minmax,达成类似那种“流动布局”的效果。
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
这段代码所表示的意思是,每一列的最小宽度为200px,要是容器足够宽阔,那么就要放置尽量多的列,而且每一列的宽度是相等的,当容器变狭窄的时候,列的数量会自动减少,每一列依旧不会小于200px。这便是通过纯CSS实现的响应式卡片墙!
三、网格线:定位的坐标系
那些网格借助网格线分隔而成,比方说,3列之中存在4条纵向网格线,其编号自1起始,2行之内有3条横向网格线,凭借这些线能够精准放置项目。
.item {
grid-column-start: 1;
grid-column-end: 3; /* 从第1条纵向线跨到第3条线,即占据前两列 */
grid-row-start: 1;
grid-row-end: 3; /* 从第1条横向线跨到第3条线,即占据前两行 */
}
简写为:
.item {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
也可以从哪条线开始,并指定跨度:
.item {
grid-column: 1 / span 2; /* 从第1列开始,跨2列,等同于1/3 */
grid-row: 1 / span 2;
}
网格线是能够进行命名的,举例来说,像grid-template-columns这样的情况 ,是可以的。
main-start
1fr ,然后使用命名来定位。
四、网格区域:给格子起名字
如若你感觉采用线编号这种方式缺乏足够直观性,那么能够给网格区域赋予名称,借助grid-template-areas属性去划分区域。
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 100px 1fr 100px;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
}
.header {
grid-area: header;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.aside {
grid-area: aside;
}
.footer {
grid-area: footer;
}
如此这般的布局清晰得仿若图纸那般,每一个区域的名称径直对应着一个网格单元格,留意,其中的grid-template-areas里的每一个单元格都势必得填满,绝不能够有空洞存在,能够用.去指代空单元格。
五、间距与对齐:让网格透气1. 行列间距
通过gap属性,来对网格线之间的间距予以设置,可以分别针对行间距以及列间距进行设置。
.container {
gap: 20px; /* 行列间距都是20px */
row-gap: 10px; /* 单独设置行间距 */
column-gap: 15px; /* 单独设置列间距 */
}
2. 项目在单元格内的对齐
项目默认填满整个单元格,但你可以控制它们的位置。
.container {
justify-items: center; /* 所有项目水平居中 */
align-items: center; /* 所有项目垂直居中 */
}
要是打算单独操控某一个项目,那就去使用justify - self以及align - self。
3. 整个网格在容器内的对齐
假如网格的总体尺寸比容器小,那么能够运用justify - content以及align - content去把控网格整体的对齐情况,这和Flexbox相类似。
.container {
justify-content: center; /* 网格整体水平居中 */
align-content: center; /* 网格整体垂直居中 */
}
采用的值同样是start,采用的值同样是end,采用的值同样是center,采用的值同样是space - between,采用的值同样是space - around,采用的值同样是space - evenly。
六、实战:用Grid搭建常见布局1. 经典三栏布局(圣杯)
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
gap: 20px;
}
就这么简单,三栏就出来了,而且中间自适应。
2. 响应式卡片墙
我们希望卡片最小200px,尽量填满容器,而且自动换行。
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
无论容器多宽,卡片都会自动调整列数,完美响应式。
3. 不规则布局:杂志风格
比如一个封面图占两列,下方三个卡片各占一列。
封面大图
卡片1
卡片2
卡片3
.magazine {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.feature {
grid-column: 1 / -1; /* 从第一列线到最后一列线,即占满整行 */
}
-1表示最后一条网格线,很方便。
4. 后台管理仪表盘
常存在于后台的复杂区域划分,运用grid-template-areas是最为合适的。
.dashboard {
display: grid;
grid-template-columns: 250px 1fr 300px;
grid-template-rows: 80px 1fr 60px;
grid-template-areas:
"header header header"
"sidebar main widgets"
"footer footer footer";
height: 100vh;
}
各区域对号入座,结构一目了然。
5. 叠加效果
Grid能够使多个元素出现重叠的情况,借助为它们设定相同的网格区域,接着运用z-index来对层级加以控制。
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.item1 {
grid-area: 1 / 1 / 2 / 3; /* 占满整行 */
background: red;
z-index: 1;
}
.item2 {
grid-area: 1 / 2 / 2 / 3; /* 只占第二列 */
background: blue;
opacity: 0.5;
z-index: 2; /* 显示在上层 */
}
七、Grid vs Flexbox:怎么选?
好些人在何时运用Grid,何时运用Flexbox这个问题上犯难,实际上挺容易的:
它们并非是替代的那种关系,而是属于配合的那种关系,你能够在Grid单元格之中运用Flexbox去排列其内部的元素,你也能够将Flexbox项目里头再去嵌套Grid,两者相互结合,天下就没有敌手了。
八、常见坑点与避坑指南1. 默认不是严格的一行一列
若是仅仅去设置display: grid,然而却不开展行列的定义,那么默认的状况下就只有一列,行数是由项目的数量来进行决定的,(每一个项目会占据一行)。所以说一定要去进行行列的定义。
2. 项目会自动填充,但可能超出网格
倘若项目数量超出网格单元格,便会施行自动创建隐式网格(也就是新起一行),而行高预设为auto。你能够借助grid-auto-rows对隐式行的高度予以调控。
.container {
grid-auto-rows: 100px; /* 隐式创建的行高100px */
}
3. fr 和 minmax 结合时注意死循环
"minmax(200px, 1fr)"所表达的内涵是,优先使得列宽呈现为1fr的状态,然而却不可能小于200px。一般情况下,此种状况并无问题,可是倘若你将所有的列均设定成如此这般,并且容器总的宽度小于列数乘以200px,那么就会出现溢出的情况(这是由于每一列都被强制规定不能小于200px)。在这个时候,可以转而采用auto-fit与minmax的精妙组合方式,或者运用max-width加以限制。
4. gap 会占用 fr 空间
在分配fr之前,间隙是会被扣除掉的。比如说三列,每列是1fr,间隙是20px,那么每列的实际宽度,等于容器宽度减去40px之后,再除以3。所以在进行计算的时候,是要考虑间隙的。
5. 网格线编号从1开始,不是0
这个容易搞错。不过可以用-1表示最后一条线,比较方便。
九、总结
由CSS给予前端开发者的Grid布局呈现成了能将网页布局转化为直观且可预测态势的一份大礼,核心要点:
Grid并非困难之事,重要的在于多多凭借自身动手去绘制格子。一旦你对这种类似“下围棋”样式的布局思维形成惯性,你就会发觉以往那些令人棘手的布局已然转变成了填空题。
假如你对这篇文章怀有喜爱之情;那么欢迎你进行赞赏、予以收藏、展开分享。明天我们会踏入 CSS 的另外一个关键话题之中;此话题乃是响应式设计同移动端适配;它会传授给你采用一套代码实现搞定手机、搞定平板及搞定电脑的方法。
明天的预告内容是,响应式设计的关键要点呢,其中包括媒体查询,还有流式布局,以及移动端适配,要从无到有去构建出一个能在全端都实现兼容的页面。