页面布局不知道如何选择?来看看Flex和Grid吧
一、前言
选择一个合适的技术,可以让你的代码更简洁、更易于维护和更具扩展性。
目前市面上比较流行的两个布局系统:CSS弹性盒子布局
和CSS网格布局
。
两者目前都可以实现比较复杂的响应式布局,但使用哪一个作为最优解,还是需要根据具体的使用情况来探讨的。
二、Flexbox
Flexbox
提供了一种有效的方式来对齐和分配容器中项目之间的可用空间。它让父元素能够直接控制其直接子元素的顺序、宽度和高度,以更好地填充可用空间。
.flex-1 {
display: flex; /* 让盒子变成flex布局 */
justify-content: space-between; /* 设置水平的主轴(X轴)的对齐方式 */
align-items: center; /* 设置垂直的交叉轴(Y轴)的对齐方式 */
border: 1px solid #909399;
width: 36rem;
height: 6rem;
border-radius: 4px;
> div {
width: 3rem;
height: 3rem;
line-height: 3rem;
color: #fff;
background-color: #007fff;
border-radius: 4px;
}
}
这样设置后,在display: flex;
的容器内的所有直接子元素都会自动的变成弹性元素,然后我们就可以单独来设置每个子元素的顺序、宽度和高度。
.flex-1 > div {
margin: 1rem;
}
.item-1 {
align-self: flex-end; /* 在Y轴的底部对齐 */
order: 0; /* 默认排序为0 */
}
.item-2 {
align-self: stretch; /* 默认值,未设置高度或设为auto,将占满整个容器 */
flex-grow: 1; /* 设置子元素放大比例,用于占据剩余的可用空间 */
order: 2; /* 设置该子元素的排序 */
}
.item-3 {
order: 1;
}
我们也可以按需求来设置按行排列
或按列排列
。
.flex-1 {
display: flex;
flex-direction: column; /* 设置为纵向列排列布局 */
align-items: stretch;
> div {
width: auto;
}
}
在flex-direction: column;
中,想让子元素自动占满父元素的宽度,则需要将子元素的宽度不设置或者设为auto,如果是正常的row
(按行排列),则需设置的是高度。
在Flexbox
中提供了一种简单的方法来反正容器内的子元素。
.flex-1 {
display: flex;
flex-direction: row-reverse;
> div {
width: 3rem;
}
}
以上的示例主要是以单排或单列来展示,Flexbox
也可以包含在多行或多列中,并且它可以根据内容和可用空间将每一行都视为一个单独的实体。
.flex-1 {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
三、Grid
Grid
允许我们在两个轴(水平和垂直)上布局,它将容器划分成行
和列
,可以让我们把子元素精准的布局在某一个格内。
先上代码:
.grid-1 {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 定义每列的宽度 */
grid-template-rows: 6rem 9rem; /* 定义每行的高度 */
gap: 1.5rem; /* 设置间距 */
}
给容器添加display: grid;
后,该容器变成了一个基础的网格布局,然后需要来设置网格的形状。
使用grid-template-columns: 1fr 1fr 1fr;
我们定义了网格将拥有的列数。我们这里定义了三列,其中的每一个值都是网格布局中单独的一列。
使用grid-template-rows: 6rem 9rem;
来定义网格的行。这里定义第一行高度为6rem
,第二行高度为9rem
。
gap
属性是用来定义行和列之间的间距,如果两个值相同,则可以简写成一个值。当然,也可以单独设置行间距和列间距grid-gap: <grid-row-gap> <grid-column-gap>;
。
以上只是一个Grid
的基础使用,接下来我们将把子元素放到你想要放入的单元格中。
这里先说明一下,默认情况下Grid
和Flexbox
一样,都是按子元素的顺序来排列的,因此,如果容器内有5个元素,那么上图就是我们网格布局的默认显示。
但是接下来的操作,我们将把第四个子元素放在第三列并占据两行。
.item-4 {
grid-column: 3 / 4;
grid-row: 1 / 3;
}
这里有个重点,我们是定义的三列两行的网格布局,但是这个4
是从哪里冒出来的?
从图中可以看到,划分网格布局生成的网格线,三列布局形成了4条垂直的网格线,网格列是按其索引来进行控制,而不是按划分出的单元格。
如果我们想把item-4
放在第三列,那我们必须使用垂直网格线3和4来定位到相应的单元格,也就是grid-column: 3 / 4;
。
接下来是grid-row: 1 / 3;
它的工作方式和上面的相同,我们让该子元素占据水平网格线1到3的单元格空间。
保存代码后可以看到效果:
这里我们可以看到,如果我们指定了某一个子元素占据单元格后,其余元素会自动的按默认排列方式自动重新排序。
在网格布局中,可能性是无穷的,完全可以按照你的需求来进行更多个性化的定制。
四、我们应该如何选择?
在此之前我们都有一个误解,认为Grid
适合网页布局而Flexbox
适合局部元素组件,因为Grid
适合构建二维布局,Flexbox
适合构建一维布局。
但是我们可以使用Flexbox
的flex-wrap
来创建二维布局,使用Grid
的基础方式来实现一维布局。尽管Flexbox
最开始不是用来构建网格布局的,但是我们在实际开发中经常按这种方式使用。
Grid
布局允许在网格中精准的放置元素。
Flexbox
更加关注与内容流,或者说更加关注元素如何在一维元素中排列。弹性盒子的子项,可以按需增长或减少自己在父容器中占据的可用空间。
在设计网页布局的时候,Flexbox
和Grid
都是很强大的工具。就像开始说的,Flexbox
主要面向的是一维布局,而Grid
是面向二维布局的。
在实际使用中,我们几乎可以使用两者一起来搭建所有的布局,但还是要决定使用哪一个来提高我们的工作效率,或者是它们更加适合的场景。同样,我们也需要知道不同端的设计图和用户的屏幕尺寸来做决定。
如果单纯的使用到Flexbox
的基础属性就能完成很好的布局而不用考虑太多的兼容性,或者只用关注内容流的布局,那么使用Flexbox
就是最好的选择,但是在Flexbox
布局的过程中,如果有子元素需要单独设计位置或者宽度/高度上出现不明确的定义,那么使用Grid
会好一些。
最主要的可能还是需要我们使用比较简洁的代码,在实现需求和功能的同时,还要考虑到不同端和多设备之间的兼容性。
参考资料:
A Complete Guide to Grid | CSS-Tricks - CSS-Tricks
转载自:https://juejin.cn/post/7148618525433659406