项目
一、认识
容器 的所有子元素自动成为容器成员,称为 Flex
项目(flex item
),简称项目。项目默认沿主轴排列。单个项目占据的主轴空间叫做main size
,占据的交叉轴空间叫做cross size
。
二、属性
2.1 order
作用: order
属性定义项目的排列顺序。数值越小,排列越靠前,默认为0
可选值: integer
应用场景:
-
应用场景一、调整项目排列顺序
场景背景: 如图所示,
Ant Design
中的X
是位于左边的, 这时交互图上X
位于右边Preview场景解决方案: 通过
order
属性将x
调整到最右边实时编辑器function TestOrder(props) { const containerStyle = { width: '200px', height: '40px', display: 'flex', alignItems: "center", justifyContent: "flex-start", } const itemSpanStyle = { order: 10, padding: '0 12px', } return ( <div style={ containerStyle }> <span style={ itemSpanStyle }>X</span> <div> Basic Drawer</div> </div> ); }
结果Loading...
2.2 flex-grow
作用: 规定了 flex-grow
项在 flex
容器中分配剩余空间的相对比例, 即 flex-grow
属性定义项目的放大比例
-
剩余空间 = 父容器空间
width
- 各个项目的basis/width
总和 -
如果所有项目的
flex-grow
属性都为1
,则它们将等分剩余空间。如果一个项目的flex-grow
属性为2
,其他项目都为1
,则前者占据的剩余空间将比其他项多一倍。
可选值: number
类型, 负值无效。 默认为 0
(如果值为 0
, 即便有剩余空间, 也不会为其分配; 换句话说, 值为 0
, 即便有剩余空间, 也不放大)
规则:
-
如果只有一个
flex
元素设置了flex-grow
属性值:-
如果
flex-grow
值小于1
: 则分配给它的是总剩余空间和这个比例的计算值。例如一个0.5
的元素能分到一半的剩余空间 -
如果
flex-grow
值大于1
: 则独享所有剩余空间
-
-
如果有多个
flex
元素设置了flex-grow
属性值-
如果
flex-grow
值总和小于1
: 则分配给元素的是总剩余空间和当前元素设置的flex-grow
比例的计算值。例如一个0.1
和一个0.2
的元素,只能分别分到1/10
和2/10
的剩余空间,剩下的剩余空间并不会分配给它们。项目所占空间计算公式如下:-
剩余空间为:
容器宽度 - 项目宽度总和
-
剩余空间每份大小为:
剩余空间 / (各个项目 flex-grow 总和) / 10
-
每个项目分配的空间为:
项目自身宽度 + (剩余空间每份大小 * 项目自身 flex-grow)
-
-
如果
flex-grow
值总和大于1
: 则所有剩余空间被利用,分配比例就是flex-grow
属性值的比例。项目所占空间计算公式如下:-
剩余空间为:
容器宽度 - 项目宽度总和
-
剩余空间每份大小为:
剩余空间 / (各个项目 flex-grow 总和)
-
每个项目分配的空间为:
项目自身宽度 + (剩余空间每份大小 * 项目自身 flex-grow)
-
-
应用场景:
-
场景一、给项目占据指定剩余空间
场景背景: 现有一个容器, 宽度为
300px
, 有三个项目a
、b
、c
, 占据容器的空间分别为:1
、2
、1
场景解决方案: 根据
flex-grow
来指定项目占据剩余空间实时编辑器function Test(props) { const containerStyle = { width: '300px', height: '100px', display: 'flex', backgroundColor: "red" } const itemAStyle = { flexGrow: 1, backgroundColor: "yellow" } const itemBStyle = { flexGrow: 2, backgroundColor: "blue" } const itemCStyle = { flexGrow: 1, backgroundColor: "green" } return ( <div style={ containerStyle }> <div style={ itemAStyle }></div> <div style={ itemBStyle }></div> <div style={ itemCStyle }></div> </div> ); }
结果Loading... -
场景二、对于
给项目占据指定剩余空间
场景的思考场景背景: 根据
给项目占据指定剩余空间
场景,我们知道了根据flex-grow
来指定项目占据剩余空间, 那么如果我们指定其中一个项目宽度了呢? 会发生什么现象?场景探究:
实时编辑器function Test(props) { const containerStyle = { width: '300px', height: '100px', display: 'flex', backgroundColor: "red" } const itemAStyle = { flexGrow: 1, width: "100px", backgroundColor: "yellow" } const itemBStyle = { flexGrow: 2, backgroundColor: "blue" } const itemCStyle = { flexGrow: 1, backgroundColor: "green" } return ( <div style={ containerStyle }> <div style={ itemAStyle }></div> <div style={ itemBStyle }></div> <div style={ itemCStyle }></div> </div> ); }
结果Loading... -
场景三、通过
flex-direction: column + flex-grow: 0.5
实现垂直居中场景背景: 如何实现垂直居中呢?
场景解决: 通过
flex-direction: column + flex-grow: 0.5
实现垂直居中实时编辑器function Test(props) { const containerStyle = { width: '100px', height: '100px', display: 'flex', backgroundColor: "red", flexDirection: "column" } const itemStyle = { flexGrow: "0.5" } const centerItemStyle = { width: '80px', height: "80px", backgroundColor: "green", } return ( <div style={ containerStyle }> <div style={ itemStyle }></div> <div style={ centerItemStyle }></div> </div> ); }
结果Loading...
2.3 flex-shrink
作用: 指定了 flex
元素的收缩规则, flex
元素仅在默认宽度之和大于容器的时候才会发生收缩, 其收缩的大小是依据 flex-shrink
的值
可选值: number
负值无效, 默认值为1
(值为 1
时, 如果空间不足,该项目将缩小)
描述: 如果所有项目的flex-shrink
属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink
属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。
规则:
-
如果只有一个
flex
元素设置了flex-shrink
:-
flex-shrink
值小于1
: 则收缩的尺寸不完全,会有一部分内容溢出flex
容器 -
flex-shrink
值大于等于1
: 则收缩完全,正好填满flex
容器
-
-
如果多个
flex
元素设置了flex-shrink
:-
flex-shrink
值的总和小于1
: 则收缩的尺寸不完全,每个元素收缩尺寸占“完全收缩的尺寸”的比例就是设置的flex-shrink
的值 -
flex-shrink
值的总和大于1
: 则收缩完全,每个元素收缩尺寸的比例和flex-shrink
值的比例一样。项目所占空间计算公式如下:-
溢出空间为:
各个项目空间总和 - 容器空间
-
每个项目的压缩率为:
(各个项目自身空间 * 各个项目 flex-shrink) /((各个项目自身空间 * 各个项目 flex-shrink) 总和)
-
每个项目分配的空间为:
各个项目自身空间 - 各个项目压缩率 * 溢出空间
-
-
应用场景:
-
场景一、给项目指定收缩空间:
项目背景: 现有一个容器, 宽度为
300px
, 有三个项目a
、b
、c
, 项目宽度如下, 那么收缩后, 各个项目的宽度是怎么样的呢?项目探究:
实时编辑器function Test(props) { const containerStyle = { width: '300px', height: '100px', display: 'flex', backgroundColor: "red" } const itemAStyle = { flexShrink: 1, width: "200px", backgroundColor: "yellow" } const itemBStyle = { flexShrink: 2, width: "100px", backgroundColor: "blue" } const itemCStyle = { flexShrink: 1, width: "200px", backgroundColor: "green" } return ( <div style={ containerStyle }> <div style={ itemAStyle }></div> <div style={ itemBStyle }></div> <div style={ itemCStyle }></div> </div> ); }
结果Loading...
2.4 flex-basis
作用: flex-basis
指定了 flex
元素在主轴方向上的初始大小。如果不使用 box-sizing
改变盒模型的话,那么这个属性就决定了 flex
元素的内容盒(content-box
)的尺寸。当一个元素同时被设置了 flex-basis
(除值为 auto
外) 和 width
(或者在 flex-direction: column
情况下设置了height
) , flex-basis
具有更高的优先级
-
flex-basis
指明的是主轴方向的初始大小, 当flex-direction: column
时,flex-basis
代表的是height
;当flex-direction:row
时,flex-basis
代表的是width
-
如果项目设置了
flex-basis
或者width
, 那么在规划空间之前,他们会先跟父容器预约这么多的空间,然后剩下的才是归入到剩余空间, 然后父容器再把剩余空间分配给设置了flex-grow
的容器。
可选值: 默认为 auto
-
<width>
: 负值是不被允许的,-
0px / 0
: 项目不会占据容器控件, 项目最终宽度为0px
。如果项目中有内容, 则由内容撑开。 -
1px / 1
: -
30%
: 项目会占据容器的 30%
-
-
关键词
-
auto
: 默认为auto
, 即由项目的width
属性决定,如果项目没有width
,那么由项目内容决定 -
fill
: -
max-content
: -
min-content
: -
fit-content
:
-
-
自动尺寸:
content
: 基于flex
的元素的内容自动调整大小。由于最初规范中没有包括这个值,在一些早期的浏览器实现的flex
布局中,content
值无效可以利用设置 (width
或height
) 为auto
达到同样的效果
-
全局数值:
-
unset
: -
inherit
: -
initial
:
-
优先级: max-width/min-width
> flex-basis(属性值不为 auto)
> width
> box
应用场景:
-
场景一、探究
flex-basic: 0
时的情况实时编辑器function Test(props) { const containerStyle = { width: '300px', height: '100px', display: 'flex', backgroundColor: "red" } const itemAStyle = { flexBasis: 0, width: "200px", backgroundColor: "yellow" } return ( <div style={ containerStyle }> <div style={ itemAStyle }></div> </div> ); }
结果Loading...
2.5 flex
作用: flex
属性是flex-grow
, flex-shrink
和 flex-basis
的简写,默认值为0 1 auto
。后两个属性可选
可选值:
-
单值可选值:
-
无单位值: 一个无单位数它会被当作
flex:<number> 1 0
。即<flex-shrink>
的值被假定为1,然后<flex-basis>
的值被假定为0。flex: 2
: 相当于flex: 2 1 0
-
有单位值: 一个有效的宽度(
width
)值: 它会被当作<flex-basis>
的值。 -
关键字值:
-
flex: auto
: 相当于flex: 1 1 auto
, 元素会根据自身的宽度与高度来确定尺寸,但是会伸长并吸收flex
容器中额外的自由空间,也会缩短自身来适应 flex 容器。 -
flex: none
: 相当于flex: 0 0 auto
, 元素会根据自身宽高来设置尺寸。它是完全非弹性的:既不会缩短,也不会伸长来适应flex
容器。 -
flex: initial
: 相当于flex: 0 1 auto
, 元素会根据自身宽高设置尺寸。它会缩短自身以适应flex
容器,但不会伸长并吸收flex
容器中的额外自由空间来适应flex
容器 。
-
-
-
双值可选值: 第一个值必须为一个无单位数,并且它会被当作
<flex-grow>
的值。第二个值必须为以下之一:- 无单位值: 它会被当作
<flex-shrink>
的值 - 有单位值: 它会被当作
<flex-basis>
的值
- 无单位值: 它会被当作
-
三值可选值:
- 第一个值必须为一个无单位数,并且它会被当作
<flex-grow>
的值 - 第二个值必须为一个无单位数,并且它会被当作
<flex-shrink>
的值。 - 第三个值必须为一个有效的宽度值,并且它会被当作
<flex-basis>
的值。
- 第一个值必须为一个无单位数,并且它会被当作
应用场景
-
场景一、两栏布局
场景背景: 实现一个左宽为
200px
, 右宽自适应的两栏布局场景解决: 通过项目
flex: 1
实现(flex: 1 === flex: 1 1 0
)实时编辑器function Test(props) { const containerStyle = { width: '100%', height: '300px', backgroundColor: 'red', display: 'flex', } const leftStyle = { flex: "none", // flex: none === flex: 0 0 auto 不会缩短,也不会伸长 width: "200px", backgroundColor: "yellow" } const rightStyle = { flex: 1, // flex: 1 === flex: 1 1 0 即会缩短,也会伸长 backgroundColor: "blue" } return ( <div style={ containerStyle }> <div style={ leftStyle }></div> <div style={ rightStyle }></div> </div> ); }
结果Loading... -
场景二、三栏布局
场景背景: 实现一个左宽为
200px
, 右宽自适应的两栏布局场景解决: 通过项目
flex: 1
实现(flex: 1 === flex: 1 1 0
)实时编辑器function Test(props) { const containerStyle = { width: '100%', height: '300px', backgroundColor: 'red', display: 'flex', } const leftStyle = { flex: "none", // flex: none === flex: 0 0 auto 不会缩短,也不会伸长 width: "200px", backgroundColor: "blue" } const centerStyle = { flex: 1, // flex: 1 === flex: 1 1 0 即会缩短,也会伸长 backgroundColor: "yellow" } const rightStyle = { flex: "none", // flex: none === flex: 0 0 auto 不会缩短,也不会伸长 width: "200px", backgroundColor: "blue" } return ( <div style={ containerStyle }> <div style={ leftStyle }></div> <div style={ centerStyle }></div> <div style={ rightStyle }></div> </div> ); }
结果Loading... -
场景三、两栏布局(上下)
场景背景: 实现一个左宽为
200px
, 右宽自适应的两栏布局场景解决: 通过项目
flex: 1
实现(flex: 1 === flex: 1 1 0
)实时编辑器function Test(props) { const containerStyle = { width: '100%', height: '600px', backgroundColor: 'red', display: 'flex', flexDirection: "column" } const leftStyle = { flex: "none", // flex: none === flex: 0 0 auto 不会缩短,也不会伸长 height: "100px", backgroundColor: "yellow" } const rightStyle = { flex: 1, // flex: 1 === flex: 1 1 0 即会缩短,也会伸长 backgroundColor: "blue" } return ( <div style={ containerStyle }> <div style={ leftStyle }></div> <div style={ rightStyle }></div> </div> ); }
结果Loading... -
场景四、三栏布局(上下)
场景背景: 实现一个左宽为
200px
, 右宽自适应的两栏布局场景解决: 通过项目
flex: 1
实现(flex: 1 === flex: 1 1 0
)实时编辑器function Test(props) { const containerStyle = { width: '100%', height: '800px', backgroundColor: 'red', display: 'flex', flexDirection: "column" } const leftStyle = { flex: "none", // flex: none === flex: 0 0 auto 不会缩短,也不会伸长 height: "200px", backgroundColor: "blue" } const centerStyle = { flex: 1, // flex: 1 === flex: 1 1 0 即会缩短,也会伸长 backgroundColor: "yellow" } const rightStyle = { flex: "none", // flex: none === flex: 0 0 auto 不会缩短,也不会伸长 height: "200px", backgroundColor: "blue" } return ( <div style={ containerStyle }> <div style={ leftStyle }></div> <div style={ centerStyle }></div> <div style={ rightStyle }></div> </div> ); }
结果Loading...
2.6 align-self
作用: align-self
属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
可选值:
-
auto
-
flex-start: 交叉轴的起点对齐
-
flex-end: 交叉轴的终点对齐
-
center: 交叉轴的中点对齐
-
baseline: 项目的第一行文字的基线对齐
-
stretch(默认值): 如果项目未设置高度或设为
auto
,将占满整个容器的高度。