
3.3 flex布局
3.3.1 基本概念
1 flex模型
小程序使用flex模型提高页面布局的效率。这是一种灵活的布局模型,当页面需要适应不同屏幕尺寸及设备类型时该模型可以确保元素在恰当的位置。
2 容器和项目
在flex布局中,用于包含内容的组件称为容器(container),容器内部的组件称为项目(item)。容器允许包含嵌套,例如:

在上述代码中共有3个<view>组件,对于A、B来说,A是容器,B是项目;对于B、C来说,B是容器,C是项目。
3 坐标轴
flex布局的坐标系是以容器左上角的点为原点,自原点往右、往下两条坐标轴。在默认情况下是水平布局,即水平方向从左往右为主轴(main axis),垂直方向自上而下为交叉轴(cross axis),如图3-7(a)所示。用户也可以使用样式属性flex-direction: column将主轴与交叉轴的位置互换,如图3-7(b)所示。

图3-7 坐标轴对照图
4 flex属性
在小程序中,与flex布局模型相关的样式属性根据其所属标签的类型可以分为容器属性和项目属性。
容器属性用于规定容器的布局方式,从而控制内部项目的排列和对齐,如表3-22所示。
表3-22 flex布局中的容器属性

项目属性用于设置容器内部项目的尺寸、位置以及对齐方式,如表3-23所示。
表3-23 flex布局中的项目属性

例如,无法确定容器组件的宽/高却需要内部项目垂直居中,WXSS代码如下:

后续章节将详细讲解这些属性的作用。
3.3.2 容器属性
1 flex-direction属性
flex-direction属性用于设置主轴方向,通过设置坐标轴可以规定项目的排列方向。
其语法格式如下:

对属性值说明如下。
• row:默认值,主轴在水平方向上从左到右,项目按照主轴方向从左到右排列。
• row-reverse:主轴是row的反方向,项目按照主轴方向从右到左排列。
• column:主轴在垂直方向上从上而下,项目按照主轴方向从上往下排列。
• column-reverse:主轴是column的反方向,项目按照主轴方向从下往上排列。
假设有项目A、B、C 3个组件,高、宽均相同,flex-direction取不同值时的效果如图3-8所示。

视频讲解

图3-8 flex-direction属性值对照图
2 flex-wrap属性
flex-wrap属性用于规定是否允许项目换行,以及多行排列时换行的方向。
其语法格式如下:

对属性值说明如下。
• nowrap:默认值,表示不换行。如果单行内容过多,项目宽度可能会被压缩。
• wrap:当容器单行容不下所有项目时允许换行排列。
• wrap-reverse:当容器单行容不下所有项目时允许换行排列,换行方向为wrap的反方向。
这里以水平方向为例,假设有项目A、B、C、D 4个组件,宽、高均相同,flex-wrap取不同值时的效果如图3-9所示。

视频讲解

图3-9 flex-wrap属性值对照图
3 justify-content属性
justify-content属性用于设置项目在主轴方向上的对齐方式,以及分配项目之间及其周围多余的空间。
其语法格式如下:

对属性值说明如下。
• flex-start:默认值,表示项目对齐主轴起点,项目间不留空隙。
• center:项目在主轴上居中排列,项目间不留空隙。主轴上第一个项目离主轴起点的距离等于最后一个项目离主轴终点的距离。
• flex-end:项目对齐主轴终点,项目间不留空隙。
• space-between:项目间距相等,第一个和最后一个项目分别离起点/终点的距离为0。
• space-around:与space-between相似,不同之处为第一个项目离主轴起点和最后一个项目离终点的距离为中间项目间间距的一半。
• space-evenly:项目间距、第一个项目离主轴起点以及最后一个项目离终点的距离均相等。
这里以水平方向作为主轴为例,假设有项目A、B、C几个组件,宽、高完全相同,justify-content取不同值时的效果如图3-10所示。

视频讲解


图3-10 justify-content属性值对照图
4 align-items属性
align-items属性用于设置项目在行中的对齐方式。
其语法格式如下:

对属性值说明如下。
• stretch(默认值):未设置项目尺寸时将项目拉伸至填满交叉轴。
• flex-start:项目顶部与交叉轴起点对齐。
• center:项目在交叉轴居中对齐。
• flex-end:项目底部与交叉轴终点对齐。
• baseline:项目与行的基线对齐,在未单独设置基线时等同于flex-start。
这里以垂直方向作为主轴为例,假设有项目A、B、C 3个组件,宽度分别为200rpx、300rpx、400rpx(取值为stretch时暂不设置),align-items取不同值时的效果如图3-11所示。

视频讲解

图3-11 align-items属性值对照图
5 align-content属性
align-content属性用于多行排列时设置项目在交叉轴方向上的对齐方式,以及分配项目之间及其周围多余的空间。
其语法格式如下:

对属性值说明如下。
• stretch:默认值,未设置项目尺寸时将各行中的项目拉伸至填满交叉轴。当设置了项目尺寸时项目尺寸不变,项目行拉伸至填满交叉轴。
• flex-start:首行在交叉轴起点开始排列,行间不留间距。
• center:行在交叉轴中点排列,行间不留间距,首行离交叉轴起点和尾行离交叉轴终点的距离相等。
• flex-end:尾行在交叉轴终点开始排列,行间不留间距。
• space-between:行与行间距相等,首行离交叉轴起点和尾行离交叉轴终点的距离为0。
• space-around:行与行间距相等,首行离交叉轴起点和尾行离交叉轴终点的距离为行与行间间距的一半。
• space-evenly:行间间距、首行离交叉轴起点和尾行离交叉轴终点的距离相等。

视频讲解
注意:多行排列时要设置flex-wrap属性值为wrap,表示允许换行。
这里以水平方向作为主轴为例,假设有项目A~E共5个组件且宽度不同,align-content取不同值时的效果如图3-12所示。


图3-12 align-content属性值对照图
3.3.3 项目属性
1 order属性
order属性用于设置项目沿主轴方向上的排列顺序,数值越小,排列越靠前。另外,该属性值为整数。
其语法格式如下:
.item{ order: 0(默认值)| <integer> }

视频讲解
这里以水平方向为例,假设有项目A、B、C 3个组件,宽、高均相同,order取不同值时的效果如图3-13所示。

图3-13 order属性值对照图
2 flex-shrink属性
flex-shrink属性用于设置项目收缩因子。当项目在主轴方向上溢出时,通过项目收缩因子的规定比例压缩项目以适应容器。
其语法格式如下:

其属性值为项目的收缩因子,只能是非负数。
当发生溢出时,项目尺寸的收缩公式如下:
最终长度=原长度×(1-溢出长度×收缩因子/压缩总权重)
注意:当遇到小数的情况时向下取整,不进行四舍五入。
其中压缩总权重的计算公式如下:
压缩总权重=长度1×收缩因子1+长度2×收缩因子2 … +长度N×收缩因子N
注意:当从左往右为主轴时,长度指的是宽度;当从上往下为主轴时,长度指的是高度。
这里以水平方向为例,假设有项目A、B、C几个组件,宽度均为200px,分别设置项目的收缩因子为1、2、3,WXSS示例代码如下:

视频讲解

假设容器宽度仅有500px,此时3个项目的宽度之和为600px,显然会发生溢出100px的情况,因此触发收缩因子进行宽度压缩。
首先计算压缩总权重:
压缩总权重=200×1+200×2+200×3=1200px
当发生溢出时,项目尺寸的收缩公式如下:
项目A的宽度=200×(1-100×1/1200)≈183px 项目B的宽度=200×(1-100×2/1200)≈166px 项目C的宽度=200×(1-100×3/1200)=150px
由此可见,原先同样宽度的项目组件由于收缩因子不同被压缩后的宽度各不相同,并且证明了收缩因子数值越大,被压缩后的长度越短。
上述例子的示意效果如图3-14所示。

图3-14 flex-shrink应用对照图
需要注意的是,只有项目的flex-shrink属性值总和大于1时溢出长度按照实际计算,当总和小于1时溢出长度的计算公式如下:
溢出长度=实际溢出长度×(收缩因子1+收缩因子2+…+收缩因子N)
例如,上面示例中项目A、B、C的flex-shrink属性值如果分别更新为0.1、0.2、0.3,总和为0.6,小于1,则溢出长度的计算如下:
溢出长度=100×(0.1+0.2+0.3)=60px
后续的计算和前面完全一样。
3 flex-grow属性
flex-grow属性用于设置项目扩张因子。当项目在主轴方向上还有剩余空间时,通过设置项目扩张因子进行剩余空间的分配。
其语法格式如下:

其属性值为项目的扩张因子,只能是非负数。
当发生扩张时,项目尺寸的扩张公式如下:
最终长度=原长度+扩张单位×扩张因子
注意:当遇到小数的情况时向下取整,不进行四舍五入。
其中,扩张单位的计算公式如下:
扩张单位=剩余空间/(扩张因子1+扩张因子2+…+扩张因子N)
注意:当从左往右为主轴时,长度指的是宽度;当从上往下为主轴时,长度指的是高度。
这里以水平方向为例,假设有项目A、B、C 3个组件,宽度均为100px,分别设置项目的扩张因子为0、1、2,WXSS示例代码如下:

视频讲解

假设容器宽度为600px,此时3个项目的宽度之和为300px,显然会出现多出300px剩余空间的情况,因此触发扩张因子进行宽度扩张。
首先计算扩张单位:
扩张单位=300/(0+1+2)=100px
然后将剩余空间分配给项目宽度,新的项目宽度扩张公式如下:
项目A的宽度=100+100×0=100px 项目B的宽度=100+100×1=200px 项目C的宽度=100+100×2=300px
由此可见,原先同样宽度的项目组件由于扩张因子不同被扩张后的宽度各不相同,并且证明了扩张因子数值越大,被扩张后的长度越长。
上述示例的示意效果如图3-15所示。

图3-15 flex-grow应用对照图
需要注意的是,只有项目的flex-grow属性值总和大于1时扩张单位按照实际计算,当总和小于1时扩张单位就是全部的剩余空间。
例如,上面示例中项目A、B、C的flex-grow属性值如果分别更新为0.1、0.2、0.3,总和为0.6,小于1,则扩张单位就是300px。后续的计算与前面完全一样。
4 flex-basis属性
flex-basis属性根据主轴方向代替项目的宽或高,具体说明如下:
• 当容器设置flex-direction为row或row-reverse时,若项目的flex-basis和width属性同时存在数值,则flex-basis代替width属性。
• 当容器设置flex-direction为column或column-reverse时,若项目的flex-basis和height属性同时存在数值,则flex-basis代替项目的height属性。
其语法格式如下:
.item{ flex-basis: auto(默认值)| <number>px }
需要注意的是,数值比auto的优先级更高,如果flex-basis属性值为auto,而width(或height)属性值是数值,则采用数值作为最终属性值。
这里以水平方向作为主轴为例,假设有项目A、B、C 3个组件且宽度均为100px,为A追加flex-basis值为200px,最终示意效果如图3-16所示。

视频讲解

图3-16 flex-basis属性值对照图
由该图可见,项目A的宽度比B和C宽,这是因为flex-basis的优先级大于width。
5 flex属性
flex属性是flex-grow、flex-shrink、flex-basis的简写方式,其语法格式如下:

若将属性值设置为none,等价于0 0 auto;若设置为auto,等价于1 1 auto。
6 align-self属性
align-self属性设置项目在行中交叉轴方向上的对齐方式,用于覆盖容器的align-items,这么做可以对项目的对齐方式做特殊处理。
其语法格式如下:

其默认属性值为auto,表示继承容器的align-items值。如果容器没有设置align-items属性,则align-self的默认值auto表示为stretch。其他属性值参照align-items的说明。
这里以水平方向为例,假设有项目A、B、C、D 4个组件,其中A、B、C的宽/高均相同,D不定义高度,align-self取不同值时的效果如图3-17所示。

视频讲解

图3-17 align-self属性值对照图