16.弹性盒模型
A>. 弹性盒模型,按照W3C的定义来说,是为了适应不同的屏幕尺寸以及设备类型时确保元素拥有恰当的行为的布局方式;
主要作用在于,提供一种更加有效的方式来对一个容器中的子元素进行排列,对齐和分配剩余空间的布局方案;
--> 从弹性盒模型的定义描述中,我们可以发现,这种模型,主要是针对容器类元素中对子元素的布局上的控制,
--> 进而可理解: 弹性盒模型是由弹性容器与弹性子元素构成;
--> 对于父级元素之外,子元素以内是正常渲染的,与弹性盒模型无关;
B>. 弹性盒模型的应用,主要是基于对父级元素进行设置: display:flex; 来达到弹性盒模型的应用;
从上图我们可以看到,默认情况下,父元素为普通的盒模型(display:block),三个子元素是从上而下布局,每个子元素独立占一行;
当我们为父元素应用弹性盒模型时,三个子元素立即就跑到一行去了,有点像应用了 float:left的效果;但实际上却并不是应用了浮动样式;
这主要是由弹性盒模型的应用规则而产生的效果;
C>. 弹性盒模型的特性
1). 在父级元素应用弹性盒模型规则时,默认在父元素中存在二个轴,一个是主轴,一个是交叉轴,默认情况下,主轴为水平向右,交叉轴垂直向下,
与我们在3D模型中的X,Y轴一样; 子元素在弹性盒模型中,会依据主轴的方向进行排列;(默认情况下主轴向右,看起来就像我们使用了float:left效果一样了)
在应用中,我们可以通过设置 flex-direction来变更主轴与交叉轴的方向
主轴方向可设置值为: row,row-reverse,column,column-reverse; 具体变化效
2).子元素尺寸的规则
默认情况下,所有子元素沿主轴排列,不会换行,依据主轴的方向,及所有子元素的相关尺寸数据,对子元素有不同的影响
a. 当主轴方向为row 或 row-reverse时 (即主轴横向时)
** 所有子元素展示在一行上
** 当所有子元素的宽度之合小于父元素宽度时,各子元素保留自身的宽度;
当所有子元素的宽度之合大于父元素宽度时,各子元素将等比例缩小自身宽度,确保在一行上能够容下所有的子元素;
** 若未设置子元素的高度,所有子元素都将独占一列;
b. 当主轴方向为column或column-reverse时(即主轴纵向时),
** 所有子元素展示在一列上;
** 当所有子元素的高度之合小于父元素高度时,各子元素保留自身的高度;
当所有子元素的高度之合大于父元素高度时,各子元素将等比例缩小自身高度,确保在一列上能够容下所有的子元素;
(注意:若为每个子元素设置了line-height等绝对尺寸的参数,将会影响到各子元素等比例缩放的效果)
** 若未设置子元素的宽度,所有子元素都将独占一行; (此时与常规的盒模型特别相像)
3).子元素的换行处理
在默认情况下,弹性盒模型会强制性的将子元素布局在一行或一列上,并且会变更子元素的宽或高,这在实际应用中,很大情况下是有问题的,
总不能因为多加了一个动态元素而让其它的元素的尺寸跟着变化,只为了在一行或一列上展示;
为了确保父元素在一行或一列上不能容下全部子元素时,让子元素自动换行,我们可以通过设置参数: flex-wrap来进行设置
是否换行及换行方式,我们可以设置; nowrap, wrap, wrap-reverse;
** 当应用换行模式时,如果换行后,所有行/列的总高度/宽度之合超过了父元素的高度/宽度,则会超出父元素的外边框
4).子元素在主轴方向上的布局方式
在前面,我们了解到弹性盒模型中有主轴和交叉轴的概念,现在我们再来了解另外几个概念点
main start: 主由开始点; main end:主轴结束点; cross start:交叉轴开始点;cross end:交叉轴结束点;
main size: 单个子元素在主轴方向上的尺寸 cross size:单个子元素在交叉轴上的尺寸;
默认情况下,子元素在父元素内,都是从主轴的main start点开始布局, 对于子元素在父元素内怎么排列,
我们可以通过参数: justify-content来进行设置,
flex-start: 从主轴开始点开始排列; flex-end:从主轴结束点开始排列; center:居中布局;
space-between:平均分配一行内剩余空间作为各个子元素之间的距离; 即: 剩余空间 / (元素个数-1)
space-around: 平均分配一行内剩余空间,作为每个元素左右/上下的空闲距离;即 剩余空间/ (元素个数*2)
** 无论哪种排列模式,各行/列是整体布局的,即一行/列内,元素的先后关系是不会发生变化的
5).单个子元素在交叉轴上的对齐布局方式
默认情况下,子元素在父元素内,都是从交叉轴的cross start点开始布局, 对于子元素在父元素内怎么排列,
我们可以通过参数: align-items来进行设置,
flex-start: 从交叉轴开始点开始排列; flex-end:从交叉轴结束点开始排列; center:居中布局;
stretch:默认情况,若未设置高度,子元素将铺满整列或整行
baseline:第一行的文本基线为对齐标准;(这个对齐规则与行内元素的对齐规则有点不一样,这里仅考虑第一行文本)
》》》align-items是用来统一控制子元素在交叉轴上的对齐规则,
》》》align-self:这个属性是用来独立控制单个子元素在交叉轴上的对齐规则;
align-self相较于 align-items来说,多了一个auto的取值, 如果设置了auto值,则表示子元素按照align-items中设置的属性进行设置
6).当子元素存在换行时,各行之间在父元素中的布局方式
我们通过 align-content来进行设置,主要控制子元素按行或按列为整体,在交叉轴上的对齐规则
7).子元素在父元素存在剩余空间或空间不足以容纳所有子元素时的尺寸变更规则
flex-grow: 默认为0, 取正值, 每个子元素都可以设置; 当父元素存在剩余空间时,用以标识各个不同的子元素,按什么样的比例分配父元素的剩余空间
每个子元素可分配到的扩展剩余空间尺寸为: 剩余空间尺寸*(子元素自身增长因子/所有子元素增长因子之合)
flex-shrink: 默认为1, 取值>=0,当父元素宽度或高度不足以容纳全部子元素且未开启换行参数时,为确保父元素容纳下所有的子元素,每个子元素需要缩小的尺寸
每个子元素需要扣减的尺寸为:(子元素尺寸之合-父元素尺寸)*(子元素缩小因子/全部子元素缩小因子之合)
flex-basis: 这个属性定义了在分配父元素剩余空间之间,子元素占据的主轴空间尺寸,浏览器依据这个属性值,计算主轴上是否还有剩余的空间;
a.直接设置尺寸,flex-basis:1000px; 这个属性值一设置,则其对应的width或height属性就无效了(无论尺寸数据设置在本项参数前还是后,都无效)
b.设置百分比,flex-basis:50%; 这个百分比,用于标识子元素的尺寸是父元素相应尺寸的百分比,即父元素宽或高的50%;
c. 设置content: 表示依据子元素的内容来决定尺寸;
d.设置auto值; 系统将检测是否设置了width或height值,如果设置了就以设置值为标准;
具体使用width还是height,由flex-direction来决定;
如果没有设置width或height值,则默认为content值;
8). 对子元素尺寸数据的统一设置
flex: flex-grow flex-shrink flex-basis;
本属性值默认为 flex: 0 1 auto; 表示有剩余空间时不增长 空间不足时大家等比例扣减主轴尺雨 子元素尺寸若设置了尺寸就按尺寸/没设置就按内容来
基于上述默认情况,flex属笥还有二个简写值,即
flex:none; 等价于 flex: 0 0 auto;
flex:auto; 等价于 flex: 1 1 auto;
9).关于子元素定位展示顺序的控制
针对于子元素,还可以单独的控制子元素具体展示在第几位;
这个规则主要是通过 order属性来控制,
因为这个参数使用起来,非常容易打乱子元素的整体规则,所有一般情况下不推荐使用;