Flex布局,是W3C在2009年提出的一种新的方案,可以简便,完整,响应式的实现各种页面布局。
微信小程序上也可以使用flex布局,今天就来介绍一下flex布局的用法.
如果要使用flex布局,样式上需要添加display: flex;
flex布局存在两根轴,主轴和交叉轴,任何一条轴都可以出现在水平方向或者垂直方向,假设主轴在水平方向,那么交叉轴就在垂直方向,反之亦然。
flex-direction属性
该属性就是用来控制主轴在那个方向上的.它有4个可选值:
- row(默认值):主轴为水平方向,起点在左端。
- row-reverse:主轴为水平方向,起点在右端。
- column:主轴为垂直方向,起点在上沿。
- column-reverse:主轴为垂直方向,起点在下沿。
下面分别演示
在wxml文件中定义2个布局,分别演示水平和垂直的布局
<!-- 主轴在水平方向 -->
<view class="flex-row">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-item">3</view>
</view>
<!-- 主轴在垂直方向 -->
<view class="flex-column">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-item">3</view>
</view>
在wxss文件中添加样式
.flex-row {
background: blue;
display: flex;
flex-direction: row;
margin-bottom: 20rpx;
}
.flex-column {
background: blue;
display: flex;
flex-direction: column;
margin-bottom: 20rpx;
}
.flex-view-item {
width: 50rpx;
height: 50rpx;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
效果如下,分别表示row和column的效果
如果分别把flex-direction改成row-reverse
和column-reverse
的效果如下:
可见,不仅起点改变了,里面的元素排序也改变了
flex-wrap属性
用于规定子元素在主轴上的换行方式,有3个取值:
- nowrap(默认):不换行,子view宽高会被挤压。
- wrap:换行,第二行在第一行的下方(前提主轴是水平)
- wrap-reverse:换行,第二行在第一行的上方(前提主轴是水平)
如果主轴是水平方向换行的话,可以有简写的方式flex-flow: row wrap;
在wxml中添加2布局,同样分别演示主轴在水平和垂直方向的换行方式
<view class="flex-row-wrap">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-item">3</view>
<view class="flex-view-item">4</view>
<view class="flex-view-item">5</view>
<view class="flex-view-item">6</view>
<view class="flex-view-item">7</view>
<view class="flex-view-item">8</view>
<view class="flex-view-item">9</view>
<view class="flex-view-item">10</view>
<view class="flex-view-item">11</view>
<view class="flex-view-item">12</view>
<view class="flex-view-item">13</view>
<view class="flex-view-item">14</view>
<view class="flex-view-item">15</view>
</view>
<view class="flex-column-wrap">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-item">3</view>
<view class="flex-view-item">4</view>
<view class="flex-view-item">5</view>
<view class="flex-view-item">6</view>
<view class="flex-view-item">7</view>
<view class="flex-view-item">8</view>
<view class="flex-view-item">9</view>
<view class="flex-view-item">10</view>
<view class="flex-view-item">11</view>
<view class="flex-view-item">12</view>
<view class="flex-view-item">13</view>
<view class="flex-view-item">14</view>
<view class="flex-view-item">15</view>
</view>
在wxss中添加2个样式
.flex-row-wrap {
background: blue;
margin-bottom: 20rpx;
width: 300rpx;
height: 300rpx;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.flex-column-wrap {
background: blue;
width: 300rpx;
height: 300rpx;
margin-bottom: 20rpx;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
效果图如下:
如果将flex-wrap改成wrap-reverse
,效果如如下:
可以发现这张图的效果刚好和上面那张的效果相反.
在来看看默认的效果图,也就是将flex-wrap改成nowrap
或者去掉flex-wrap样式后的效果:
很显然,这个效果不是我们想要的,子元素直接超出父容器的范围了.当然啦,如果你想要实现超出父容器不显示,你只需要添加这个样式overflow: hidden;
即可,这个css样式就有这个属性,小程序上也可以使用,效果如下:
align-content属性
不知道你们有没有发现上面设置flex-wrap属性的时候,无论是水平方向换行还是垂直方向换行,行与行之间都会存在一个距离,这个距离要怎么控制呢?
align-content属性就是用来解决子元素行与行之间在交叉轴的排列方式,一共有6个值:
- flex-start :各行位于容器交叉轴的开头。
- flex-end :各行位于容器交叉轴的结尾。
- center :各行位于容器交叉轴的中心。
- space-between :各行之间留有空白的容器内。
- space-around :各行之前、之间、之后都留有空白的容器内。
- stretch(默认值):各行子元素在交叉轴上被拉伸以适应容器(前提是子元素没有设置宽高信息)
下面分别演示一下,布局还是flex-wrap的那个布局,样式的话修改成如下:
.flex-row-wrap {
background: blue;
margin-bottom: 20rpx;
width: 300rpx;
height: 300rpx;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: flex-start
}
.flex-column-wrap {
background: blue;
width: 300rpx;
height: 300rpx;
margin-bottom: 20rpx;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start
}
添加 align-content: flex-start
的效果图如下:
改成align-content: flex-end
的效果如下:
改成align-content: center
的效果如下:
改成align-content: space-between
的效果如下:
改成align-content: space-around
的效果如下:
改成align-content: stretch
的效果如下:
发现效果就和没有设置align-content属性的效果一样,由于子元素都设置了宽高信息,所以stretch的效果看得不是很明白,所以我将子元素的宽高信息去掉后的效果如下:
可以看到各行在交叉轴上是进行了拉伸的。
justify-conent属性
用于定义子元素在主轴上面的对齐方式,有5个可选的对齐方式:
- flex-start: 主轴起点对齐(默认值)
- flex-end: 主轴结束点对齐
- center: 在主轴中居中对齐
- space-between: 两端对齐,除了两端的子元素分别靠向两端的容器之外,其他子元素之间的间隔都相等
- space-around :每个子元素之间的距离相等,两端的子元素距离容器的距离也和其它子元素之间的距离相同。
由于主轴可出现在水平方向,也可以出现在垂直方向,开篇介绍flex-direction属性的时候就说了,所以下面我还是同时演示justify-conent属性在分别在水平和垂直方向主轴上的设置效果。
在wxml文件中添加2个布局,分别表示水平主轴和垂直主轴的布局
<view class="flex-row-justify">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-item">3</view>
</view>
<view class="flex-column-justify">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-item">3</view>
</view>
在wxss文件中添加样式
.flex-row-justify {
background: blue;
margin-bottom: 20rpx;
display: flex;
flex-direction: row;
justify-content: flex-start;
}
.flex-column-justify {
background: blue;
margin-bottom: 20rpx;
height: 300rpx;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
/* 子元素的样式 */
.flex-view-item {
width: 50rpx;
height: 50rpx;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
添加 justify-content: flex-start
的效果图如下:
改成 justify-content: flex-end
的效果图如下:
改成 justify-content: center
的效果图如下:
改成 justify-content: space-between
的效果图如下:
改成 justify-content: space-around
的效果图如下:
align-items属性
用于定义子元素在交叉轴上对齐的方式,同样也有5种对齐方式,但是会有所不同
- flex-start 侧轴的起点对齐
- flex-end 侧轴的终点对齐
- center 在侧轴中居中对齐
- stretch 填充整个容器(默认值),如果子元素设置了宽高,则无效
- baseline 以子元素的第一行文字对齐
在wxml文件中添加2个布局,分别表示水平主轴和垂直主轴的布局
<view class="flex-row-align">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-item">3</view>
</view>
<view class="flex-column-align">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-item">3</view>
</view>
在wxss文件中添加样式
.flex-row-align {
background: blue;
margin-bottom: 20rpx;
height: 200rpx;
display: flex;
flex-direction: row;
align-items: flex-start;
}
.flex-column-align {
background: blue;
margin-bottom: 20rpx;
height: 200rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
}
/* 子元素的样式 */
.flex-view-item {
width: 50rpx;
height: 50rpx;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
添加 align-items: flex-start
的效果图如下:
改成 align-items: flex-end
的效果图如下:
改成 align-items: center
的效果图如下:
改成align-items: stretch
的效果图如下:
发现效果和 align-items: flex-start
没啥区别,这是因为stretch需要将子元素的宽高去掉才有效果,下面是去掉后的效果:
改成 align-items: baseline
的效果图如下:
你会发现和 align-items: flex-start
没啥区别,这是因为我这里的每个子元素的内容就只有一个数字,而且子元素的宽高也一样,为了看到效果,我需要调整一下布局和样式,一个个来,我先调整水平flex的布局和样式
<view class="flex-row-align">
<view class="flex-view-item1">1</view>
<view class="flex-view-item2">2</view>
<view class="flex-view-item3">3</view>
</view>
.flex-row-align {
background: blue;
margin-bottom: 20rpx;
height: 300rpx;
display: flex;
flex-direction: row;
align-items: baseline;
}
.flex-view-item1 {
height: 50rpx;
width: 50px;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
.flex-view-item2 {
line-height: 150rpx;
height: 150rpx;
width: 50px;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
.flex-view-item3 {
height: 250rpx;
line-height: 250rpx;
width: 50px;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
效果图如下:
可以看到水平flex布局上的3个子View在交叉轴上的对齐方式是基于第一个子View的文本中心对齐的,它们的文本是在同一个基线上的。
同理,修改下垂直flex布局和样式,然后查看效果
<view class="flex-column-align">
<view class="flex-view-item4">1</view>
<view class="flex-view-item5">2</view>
<view class="flex-view-item6">3</view>
</view>
.flex-column-align {
background: blue;
margin-bottom: 20rpx;
height: 200rpx;
display: flex;
flex-direction: column;
align-items: baseline;
}
.flex-view-item4 {
height: 50rpx;
width: 50px;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
.flex-view-item5 {
height: 50rpx;
width: 150px;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
.flex-view-item6 {
height: 50rpx;
width: 250px;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
}
效果如下:
发现,并没什么卵用。感觉垂直flex布局中设置align-items: baseline
和align-items: flex-start
效果是一样的.
align-self属性
也是表示子元素在交叉轴上的对齐方式,只不过是作用在单个子元素上,而不是作用在父容器flex布局上。
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
继续在wxml文件中添加2个布局
<view class="flex-row-self">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-self">3</view>
</view>
<view class="flex-column-self">
<view class="flex-view-item">1</view>
<view class="flex-view-item">2</view>
<view class="flex-view-self">3</view>
</view>
在wxss文件中添加样式
.flex-row-self {
background: blue;
margin-bottom: 20rpx;
width: 250rpx;
height: 250rpx;
display: flex;
flex-direction: row;
}
.flex-column-self {
background: blue;
width: 250rpx;
height: 250rpx;
margin-bottom: 20rpx;
display: flex;
flex-direction: column;
}
.flex-view-self{
width: 50rpx;
height: 50rpx;
text-align: center;
border: 1rpx solid black;
background: red;
color: white;
align-self: flex-end
}
效果图如下:
可以看到子View3单独设置了align-self: flex-end
样式后,其在交叉轴的对齐方式就和其他的子View不一样了.