JavaScript五十问——对比来说CSS的Grid与FlexBox(上篇)

29次阅读

共计 4378 个字符,预计需要花费 11 分钟才能阅读完成。

前言
春节假期有幸拜读了张鑫旭大大的关于 Flex 与 Grid 的两篇文章(见参考文献),很有收获;自己在开发的过程中,很多时候都会采用 Flex 布局,而 Float 与 inline-box 这种方式已经很少使用了;这次在春假期间学习了 Grid,深感 Grid 的好用与便利。趁着这次机会总结一下 Grid 与 Flex 的使用。
浏览器支持
Flex 浏览器支持情况

Grid 浏览器支持情况

可以看出来,相对于 Grid 来说,Flex 无论实在 PC 端还是移动端都得到了很好的支持,而 Grid,在移动端的支持还是差强人意。
FlexBox
在 flex 布局中,有两个概念需要谨记:容器与元素。在一个 html 标签中声明样式:display:flexordisplay:inline-flex 即声明了一个 flex 的容器,在这个容器里面的元素即为 flex 元素。而 flex 所有的样式属性分为两类:容器属性与元素属性,他们均作用于 flex 元素,只不过 flex 容器中声明的属性统领 flex 所有元素整体显示与排布方式,而 flex 元素的属性表示单一元素的排布方式。

下面,根据上面脑图的思路,依次介绍 flex 的属性。声明:下面师范的所有元素都遵从以下 HTML 结构 和基本样式
<style>
.container{
height:200px;
background-color:#999;
}
.container >.item{
background-color:#456;
width:80px;
font-size:30px;
color:white;
text-align:center;
}
</style>
<div class=”container”>
<div class=”item”>1</div>
<div class=”item”>2</div>
<div class=”item”>3</div>
<div class=”item”>4</div>

</div>

容器属性
flex-direction
flex-direction 顾名思义,是控制 flex 元素的整体布局方向的,它包括四个属性:
1.row // 从左到右 默认
2.row-reverse // 从右到左
3.column // 从上到下
4.column-reverse // 从下到上
1、flex-direction:row
2.flex-direction:row-reverse
3.flex-direction:column4.flex-direction: column-reverse
上面四个图是分别在容器上(.container)设置 flex-direction 四个属性得到的效果。
flex-wrap
flex-wrap 是控制元素是换行显示还是单行显示,它共有三个属性
1.no-wrap // 不换行 默认
2.wrap // 换行
3.wrap-reverse // 换行反序
为了更加明显的看出区别,我特别添加了一个难看的边框。在容器属性上添加 flex-wrap, 分别设置三个 wrap 属性 1.flex-wrap: no-wrap

2.flex-wrap: wrap
3.flex-wrap: wrap-reverse 在这里需要注意 no-wrap 属性:如果容器元素设置了最小宽度,而且元素的最小宽度之和 > 父容器的宽度,则显示内容溢出。如果容器元素没有设置最小宽度或者最小宽度之和 < 父容器的宽度,则容器元素收缩并将父元素填满,在上面 no-wrap 例子中,就没有设置子元素的最小宽度,读者可以自行添加验证。
设置 wrap-reverse 属性后,我们可以看到它的换行结果与 wrap 的换行结果在行这一维度上是相反的。
读者可以试试将 flex-direction 设置为 column 或者其他非默认值,再查看在不同的 flex-wrap 值下的显示,会有不同的结果哟。
flex-flow
flex-flow 是 flex-direction 与 flex-wrap 的统写,语法是 flex-flow:<‘flex-direction’> || <‘flex-wrap’>
justify-content
justify-content 控制 flex 元素水平方向的对齐方式,它共有 个属性:
1.flex-start // 默认值 默认情况下左对齐 2.flex-end // 右对齐 3.center // 居中下面以 space 开头的属性都是描述剩余空间的排布方式的 4.space-around // 剩余空间围绕在每个子元素的周围 5.space-between // 剩余空间只分布在子元素之间,两端元素左右没有剩余空间 6.space-evenly // 剩余空间均匀分布在元素两端、之间
下面看例子:1.flex-start

2.flex-end

3.center

4.space-between

5.space-around

6.space-evenly 为了更加明显的看出不同 space 下的额外空间分布特点,我使用红框框出每一属性下的剩余元素。几个属性分布不同不言而喻了。
align-content
align-content 与 justify-content 对应,代表元素垂直方向上的分布。而这种分布方式只有在多行的情况下才能够凸显出来,单行情况下设置此属性无效。相对于 justify-content,它多出来一个 stretch 的属性,代表拉伸, 默认属性。
1.stretch

2.flex-start

3.flex-end

4.space-between

5.space-around

6.space-evenly

可以看出,它的排布方式与 justify-content 的逻辑是一致的,只不过方向不同而已。
align-items
既然有了多行情况下控制元素排布方式,就会有单行情况下元素排布方式。align-items 就是在单行情况下,控制元素排布方式的。共有 5 个属性:1.stretch 默认属性,会将元素的高度拉伸至父容器的高度

2.flex-start 顶部对齐

3.flex-end 底部对齐

4.baseline 基线对齐

5.center 居中

注意:以上所有的例子展示都是在其他属性默认情况的显示情况,如果更改其他属性 (如:flex-direction 与 flex-wrap) 值,会有不同的显示效果。
元素属性
order
order 属性可以控制 flex 元素的排布顺序,flex 元素会根据 order 从小到大依次排布,order 的默认值为 0,因此如果想要某个元素排在前面,只需要将他的 order 值设为比 0 小的值即可。
flex-grow
flex-grow 控制元素所占宽度,默认值为 0,当容器内有剩余空间时,flex-grow 不为 0 的元素将会按照以下规则扩展:
容器中只有一个元素设置了 flex-grow 1、flex-grow 值 >=1 那么这个元素会填充容器的剩余空间

.container .item:first-child{
order:2;
flex-grow:1;
}
2、flex-grow 在 0 - 1 之间,那么这个元素会多占用空间为剩余空间乘以这个 flex-grow 的值。

.container .item:first-child{
order:2;
flex-grow:0.5;
}

.container{
display:flex;
justify-content:space-around;// 如果子元素的 flex-grow<1, 此属性依然有效
}

.container .item:first-child{
order:2;
flex-grow:0.5;
}
容器中有多个元素设置了 flex-grow1、所有元素的 flex-grow 的值之和 >1 则占用全部的剩余空间,多占用的剩余空间比例即为各个元素所设置 flex-grow 的比例。2、所有元素的 flex-grow 的值之和 <1 所占用的剩余空间的比例即为各个元素的 felx-grow 的值的比例。
flex-shrink
flex-shrink 的属性与 flex-grow 相反,指的是当空间不足的时候,元素的收缩比例,默认值为 1;其核心思路与 grow 一致,这里不再赘述,读者可以自行检验。
flex-basis
flex-basis 定义了在分配剩余空间之前,每个元素的默认宽度,默认为 auto 即元素的宽度;当 flex-basis 的值不为 auto 时,其显示的优先级是高于元素的 width 的。
flex
flex 属性为以上三个属性的统称,语法为:flex: none | auto | [<‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’>]flex 翻译为中文就是弹性的,所以这个属性就是说明当有空间过大 or 空间不足时,每个元素如何分布。
align-self
align-self 顾名思义,就是确定单个元素垂直分布状态;其在父容器对应的属性是 algin-items;其属性值有 align-items 一致,只不过多了一个 auto 默认属性,表示与父元素的 auto-items 值一致。来看例子:
对应 css 代码:
.container{
display:flex;
align-items:center;
}

.container .item:nth-child(2n+1){
order:2;
flex-grow:2;
align-self:flex-start;
}

我在父元素上添加 align-items 属性,使 flex 元素居中对齐,在子元素上添加 align-self 属性,使奇数子元素向上对齐。
当有多行的情况下,但是 align-content 未设置,我们可以看到,每一个设置了 align-self 属性的子元素会在当前的行按照 align-self 属性显示,但是当 align-content 属性设置后,其 align-self 属性失效(见下图)。
对应代码:
.container{
display:flex;
align-content:center;
flex-wrap:wrap;
}

.container .item:nth-child(2n+1){
order:2;
flex-grow:2;
align-self:flex-start;
}

总结
flex 布局就总结到这里,里面有些类似属性没有举例子,还需要读者自己去验证。相对于其他解决方案,flex 布局更加简洁,也更加具有语义性;最显而易见的,可以很方便的解决我们平时面试过程中遇到的多栏布局,垂直居中问题。其实细细品读 flex,相比于 Grid 而言,他还是更加线性化,就是把所有的元素都看成一条线,确定这条线的方向、居中垂直方式,当这条线超过父元素的范围,我们怎样处理。所以,虽然 flex 看似有许多属性,但是合理的理解后,还是非常简单的。
这篇是 glex 与 Grid 的上篇,主要介绍了 flex,而 Grid 的相关属性与应用,我们下篇见。
参考文献
张鑫旭:写给自己看的 display: flex 布局教程阮一峰:Flex 布局教程

正文完
 0