许多人都对flex布局感到头疼,在主轴交叉轴上变来变去,每次使用的时候记不住,只能一个个去试试,看看能够出现什么效果,试出来符合自己的要求了,那就万事大吉,跳过下一个,之后再用的时候又去试一遍,这样效率就十分的低下了。
一、什么是主轴和交叉轴?
这个概念是必须理解的,能否畅快的玩转flex布局,重点就是这两个轴了,理解这个万事大吉。主轴和交叉轴在默认情况下,可以看做是一个第四象限的坐标轴,在坐标轴里的x轴就是我们的主轴,y轴就是我们的交叉轴。项目主轴上排列,排满后在交叉轴方向换行。交叉轴垂直于主轴,它的方向取决于主轴方向。
可以参考下图,当第一行满了以后,item4就被排到了交叉轴第二行,如果主轴的方向发生了改变,交叉轴的方向也会随之变化。
二、flex的属性介绍
flex布局的属性有很多,一般我们将这些属性归为两大类,一类是设置容器本身的,容器也就是你想使用flex布局的标签,通俗的将就是在css里声明了display: flex,一类是设置容器里面的项目的,项目就是被你容器标签所包裹的所有子元素。
(一)容器属性
1、flex-direction 属性
row(默认值):主轴横向,方向为从左指向右。项目沿主轴排列,从左到右排列。
row-reverse:row的反方向。主轴横向,方向为从右指向左。项目沿主轴排列,从右到左排列。
column:主轴纵向,方向从上指向下。项目沿主轴排列,从上到下排列。
column-reverse:column的反方向。主轴纵向,方向从下指向上。项目沿主轴排列,从下到上排列。
2、flex-wrap 属性
设置是否允许项目多行排列,以及多行排列时换行的方向。(意思是一行排满了,是否需要换行,不换行的话,就会溢出容器,需要注意的是,这里的行不是我们单纯的横着一行行看下来,而是沿主轴方向看做一行)
nowrap(默认值):不换行。如果单行内容过多,则溢出容器。
wrap:容器单行容不下所有项目时,换行排列。
wrap-reverse:容器单行容不下所有项目时,换行排列。换行方向为wrap时的反方向。
按照上面设置排列方向为column-reverse来举个例子吧。
1、未设置换行,沿主轴方向的项目就溢出了容器 2、设置了换行,沿主轴方向来换行
3、justify-content 属性
设置项目在主轴方向上对齐方式,以及分配项目之间及其周围多余的空间。(还是以排列方向为column-reverse为例)
flex-start(默认值):项目对齐主轴起点,项目间不留空隙。
center:项目在主轴上居中排列,项目间不留空隙。主轴上第一个项目离主轴起点距离等于最后一个项目离主轴终点距离。
flex-end:项目对齐主轴终点,项目间不留空隙。
space-between:项目间间距相等,第一个项目离主轴起点和最后一个项目离主轴终点距离为0。
space-around:与space-between相似。不同点为,第一个项目离主轴起点和最后一个项目离主轴终点距离为中间项目间间距的一半。
space-evenly:项目间间距、第一个项目离主轴起点和最后一个项目离主轴终点距离等于项目间间距。
4、align-items 属性
设置项目在行中的对齐方式。(以排列方向为column-reverse为例,关键在于理解一行是什么样的概念)
stretch(默认值):项目拉伸至填满行高。
1、上面的属性测试图,我都给item设置了宽度和高度,接下来我将把宽度给去掉,体验下这个项目拉伸至行高的时候,到底是怎么一回事。可以观察到item的宽度被拉伸到了填满整个容器的宽度,这就说明如果只有一行item的时候,它的行高占据了整个容器。如果是两行的话,每行各占百分之50,以此类推。
flex-start:项目顶部与行起点对齐。(这时候项目不会被拉伸去填满行高)
center:项目在行中居中对齐。
flex-end:项目底部与行终点对齐。
baseline:项目的第一行文字的基线对齐。(由于这个属性比较特殊,我将通过排列方向为row的进行展示,这里设置了item的行高line-height属性,最后一个item的行高和前面两个不一样,这时候可以发现他们文字的基线是对齐的,附上css代码助于理解)
.item {
border: 2px solid red;
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
}
.special {
line-height: 75px;
}
5、align-content 属性
多行排列时,设置行在交叉轴方向上的对齐方式,以及分配行之间及其周围多余的空间。(以排列方向为column-reverse为例)这个都不想做图了。。。就是把主轴方向上的换成在交叉轴方向上的,为了表达清楚,
stretch(默认值):当未设置项目尺寸,将各行中的项目拉伸至填满交叉轴。当设置了项目尺寸,项目尺寸不变,项目行拉伸至填满交叉轴。
flex-start:首行在交叉轴起点开始排列,行间不留间距。
center:行在交叉轴中点排列,行间不留间距,首行离交叉轴起点和尾行离交叉轴终点距离相等。
flex-end:尾行在交叉轴终点开始排列,行间不留间距。
space-between:行与行间距相等,首行离交叉轴起点和尾行离交叉轴终点距离为0。
space-around:行与行间距相等,首行离交叉轴起点和尾行离交叉轴终点距离为行与行间间距的一半。
space-evenly:行间间距、以及首行离交叉轴起点和尾行离交叉轴终点距离相等。
(二)项目属性
1、order 属性
这回我们就以排列方式row-reverse来讲述一下吧,正好复习下。
设置项目沿主轴方向上的排列顺序,数值越小,排列越靠前。属性值为整数。
<view class="item" style="order:1">item1</view>
<view class="item" style="order:3">item2</view>
<view class="item" style="order:2">item3</view>
2、flex-shrink 属性
当项目在主轴方向上溢出时,通过设置项目收缩因子来压缩项目适应容器。属性值为项目的收缩因子,属性值取非负数。
.wrap {
margin-top: 30px;
display: flex;
flex-direction: row-reverse;
height: 500rpx;
width: 400px;
background-color: #ccc;
}
.item1 {
width: 120px;
height: 50px;
flex-shrink: 2;
background-color: rgb(203, 247, 8);
}
.item2 {
width: 150px;
height: 50px;
flex-shrink: 3;
background-color: rgb(8, 247, 235);
}
.item3 {
width: 180px;
height: 50px;
flex-shrink: 1;
background-color: rgb(247, 24, 8);
}
在这个例子中,项目溢出 400 - (120 + 150 + 180) = -50px。计算压缩量时总权重为各个项目的宽度乘以flex-shrink的总和,这个例子压缩总权重为120 * 2 + 150 * 3+ 180 * 1 = 870。各个项目压缩空间大小为总溢出空间乘以项目宽度乘以flex-shrink除以总权重:
item1的最终宽度为:120 - 50 * 120 * 2 / 870 ≈ 106px
item2的最终宽度为:150 - 50 * 150 * 3 / 870 ≈ 124px
item3的最终宽度为:180 - 50 * 180 * 1 / 870 ≈ 169px
其中计算时候值如果为小数,则向下取整。
需要注意的是,当我们将item1、item2、item3的压缩量分别改为0.1,0.2,0.3时,总压缩因子是小于1的,参与计算的溢出空间不等于完整的溢出空间。
总权重为:120 * 0.1 + 150 * 0.2 + 180 * 0.3 = 96。参与计算的溢出空间不再是50px,而是50 * (0.1 + 0.2 + 0.3) / 1 =30:
item1的最终宽度为:120 - 30 * 120 * 0.1 / 96 ≈ 116px ·item2的最终宽度为:150 - 30 * 150 * 0.2 / 96 ≈ 140px
item3的最终宽度为:180 - 30 * 180 * 0.3 / 96 ≈ 163px
3、flex-grow 属性
当项目在主轴方向上还有剩余空间时,通过设置项目扩张因子进行剩余空间的分配。属性值为项目的扩张因子,属性值取非负数。
一个宽度为400px的容器,里面的三个项目width分别为80px,120px,140px。分别对这项目1和项目2设置flex-grow值为3和1。
在这个例子中,容器的剩余空间为 400 - (80 + 120 + 140) = 60px。剩余空间按 60 / (3 + 1 + 0) = 15px进行分配:
item1的最终宽度为:80+ (15 * 3) = 125px
item2的最终宽度为:120 + (15 * 1) = 135px
item3的最终宽度为:140 + (15 * 0) =140px
需要注意一点,当项目的扩张因子相加小于1时,剩余空间按除以1进行分配。
4、flex-basis 属性
这个就没啥好说的了,当容器设置flex-direction为row或row-reverse时,flex-basis和width同时存在,flex-basis优先级高于width,也就是此时flex-basis代替项目的width属性。当容器设置flex-direction为column或column-reverse时,flex-basis和height同时存在,flex-basis优先级高于height,也就是此时flex-basis代替项目的height属性。
需要注意的是,当flex-basis和width(或height),其中一个属性值为auto时,非auto的优先级更高。
5、flex 属性
是flex-grow,flex-shrink,flex-basis的简写方式。值设置为none,等价于00 auto。值设置为auto,等价于1 1 auto。
6、align-self 属性
设置项目在行中交叉轴方向上的对齐方式,用于覆盖容器的align-items,这么做可以对项目的对齐方式做特殊处理。默认属性值为auto,继承容器的align-items值,当容器没有设置align-items时,属性值为stretch。这个还是非常有用的,如果你的某个项目有特殊的需求,不想遵循容器的align-items,那便可以设置这个属性。