H5W3
当前位置:H5W3 > 其他技术问题 > 正文

微信小程序篇:Flex布局

前置准备工作

微信小程序中经常会使用的布局这一块的知识点,如果没有一个完整的知识体系,在布局的时候,经常会出现错误使用的情况,只要你掌握这篇文章内的知识点,基本上能胜任所有的Flex布局。相比较其他文章,这个文章更侧重于开发中的实际运用。而且是以演进的角度来讲解各种布局的效果。

准备工作:为了能够讲解请求Flex布局的知识点,我们需要编辑一些前置的示例代码

首先,我们需要到classic.wxml中编写下面这段代码,其实就是三个view标签

Snipaste_2020-05-11_12-32-21

然后,再来到classic.wxss中分别设置对应的样式。

Snipaste_2020-05-10_04-08-34

最终呈现的效果会是下面这样的。你会发现,出现了三个不同颜色的小方块。

image-20200511123543358

block, inline与inline-block

编写好前置准备工作之后,不妨想一下为什么上面的三个小方块从上往下排布的,而不是从左到右排布的?

答:其实小程序的”view”类似于网页THML中的div,那么如果你熟悉div的话,就会知道它是一个块级的元素,那么块级的元素默认每一个元素是占一行的,虽然说你限制了块级元素的宽高为100px,但是本质来说它还是一个块级元素,那么就必须占一行,它不会管你块级元素宽度有多长,都会另起一行。这个是CSS的基本知识。

其实微信小程序在view标签内隐藏了一个设置。这个设置因为是默认的,因此,可以不填写的情况下也可以实现上面的效果。

# display:block  // 默认往下排布,可以不填写。
 
Snipaste_2020-05-11_12-37-45

如果此次我们希望将色块横向排布,那么需要怎么处理呢?

正常来说,我们只需要将display设置为inline。就可以了。那么我们不妨试一下。

Snipaste_2020-05-10_04-40-14

设置以后,运行一下,你会发现变成了空白了,这又是为什么呢?

答:这是因为行内元素默认数不能设置高宽。其实通过微信小程序工具也能看出这里出现了问题。

Snipaste_2020-05-10_04-44-45

那么如何解决全屏空白这个问题呢?

答:其实也挺简单的,只需要将inline换成inline-block即可。就能兼容行内元素上设置高宽,并且可以将行内元素设置为横向排布。

Snipaste_2020-05-10_04-49-07

这里有一个问题,设置成display="inline-block"一般出现在网页端设置里面,微信小程序一般不这么设置。那么如果说我们现在不设置display="inline-block"的情况下,请问如何能做到横向排布的效果呢?

答:这里需要使用到Flex布局的设置,来实现相同的效果。而不再使用到block、inline和inline-block来进行设置;

弹性盒子模型 display:flex

在使用Flex布局之前,我们需要知道什么是flex

答:flex的全称是flexible box,意思是弹性盒子,也叫做弹性布局。

说到弹性盒子,有两个基本概念需要知道的。第一个是flex container、第二个是flex item

# flex container:弹性容器
# flex item:指的是"弹性容器"下面的"子元素"。
 

解释:如果说,你需要使用到弹性布局的话,那么你最起码要有一个弹性容器(flex container),所谓弹性布局,那么就是对”弹性容器”下面的”子元素”进行flex弹性布局。

那么如果说我们需要对小色块进行弹性布局的话,那么就必须给小色块新增一个弹性容器(flex container)其实作用到项目中,还是挺简单的,我们只需要在外部添加一个view标签即可,如下所示。

Snipaste_2020-05-10_05-27-44

注意这里我们给了弹性容器view标签,设置了样式container,就是这么一段小的代码,代表的就是添加了弹性容器

Snipaste_2020-05-11_13-27-22

然后将container设置为”弹性盒子模型”,最后运行一下,你会发现这个时候的效果和之前的无异。只需要这么简单的一行代码,就能替代之前在chunk中设置的display:inline-block

Snipaste_2020-05-11_14-01-07

你会发现使用了弹性盒子模型以后,就会消除块状的特性。块状的特性:块级元素必须占一行,他不会管你块级元素宽度有多长,都会另起一行。消除块状的特性的话,那么色块就会往上排。形成上面的效果。

# 如果说,几个元素本来是一个块状的元素,一旦他们放置于一个弹性盒子容器里面的话,那么块状元素的特性就会消除掉。
那么为什么这里还要特意说明一下这一点,这是因为我们在编写代码的时候,经常会发现,已经在外部设置了弹性盒子容器了以后,但是很多同学还会在容器的子元素里面加上"display:inline-block",要知道只要在容器中设置为弹性盒子模型以后,其实完全不用再容器的子元素再次加上"display:inline-block"。因为只要在容器中设置为弹性盒子模型以后,就会消除块状的特性。这样的话块状的元素就会自动的排在一行。既然是这样的话,那么我们就不再需要"display:inline-block",否则多次一举。
#总结: flex容器将消除item的块状特性
 

flex-direction的使用

我们需要知道的是,flex-direction是用来设置弹性盒子模型的排布方向;

# flex-direction=column;  纵向排布
# flex-direction: row;    让布局处于水平分布(默认使用)
 

column 纵向排布

上面我们的色块呈现水平排布的,那么请问该如何将色块设置为纵向排布呢?

其实还是非常简单的,我们可以使用flex-direction=column;就能实现色块处于纵向排布的效果。

Snipaste_2020-05-12_02-07-44

同理,如果我们想将色块设置为横向排布,我们可以选择不设置,或者使用flex-direction=row;就可能实现。

reverse 倒序排布

为了能够更加了解reverse倒序排布的讲解,那么我们对代码进行必要的修改。

Snipaste_2020-05-12_02-24-25

然后加上1、2、3顺序。这样的话,当设置倒序排布的时候,更能显著的突出效果。

Snipaste_2020-05-12_02-27-15

接下来,我们就可以通过reverse来设置顺序排布了,我们只需要设置为flex-direction:column-reverse;就能将色块变成倒序排布,如下所示;

Snipaste_2020-05-12_02-34-49

如果我们单纯只看数字的话,就很容易觉得单纯只是色块的位置发生了变化,整体都是处于原来的左上角部分;但是我们不妨试一试使用水平方向的倒序排布,会出现一个奇怪的现象。

Snipaste_2020-05-12_02-42-02

我们不妨对比一下水平排布且正序排布的效果

Snipaste_2020-05-12_02-44-08

不难发现,当设置为水平且倒序排布的时候,色块整体会移动到最右侧。但是你在上面纵向且倒序的时候为什么没有这样的情况发生呢?是不是很奇怪,那么这里面是按照什么规律进行处理的呢?

水平且倒序,整体往右移。纵向且倒序整体不变动的原因是:纵向的高度不够,导致纵向且倒序时,无法往下移动。为了能够将这个效果呈现出来我们不妨往下看。

Snipaste_2020-05-12_03-01-18

为了能够讲解,这里面的知识点,我们打开调试器。使用调试器中的抓手工具。

Snipaste_2020-05-12_03-04-14

那么如何才能让用户看出纵向倒序其实也是会往下移动的呢?

# 原理:要知道弹性布局时,我们是没有设置高宽的,默认的情况下,弹性布局宽度是取100%的,而高度是动态取值的(自适应),也就是说纵向的时候,色块的整体有多高,那么弹性布局的高度也就有多高。
 

既然知道了原理,那么我们完全可以尝试给容器设置一个高度,我们将高度设置为400px。

首先我们需要知道的是每一个色块是100px。也就是说三个色块加起来也就300px,那么倘若纵向倒序是会往下移动的话,自然最后的效果会往下移动。我们不妨试试看。

Snipaste_2020-05-12_03-20-18

你会发现色块的整体发生了移动(向下移动),为了能够更加直观的看出效果,我们还是使用抓手工具进行查看。

Snipaste_2020-05-12_03-24-18

我们思考一下,如果我们后续懒得用抓手工具的话,如何知道色块的方向变化呢?

其实还是挺简单的,我们只需要加一个背景颜色。也能实现相同的效果。缺点就是不知道高度,如果需要知道高度是多少的话,最好还是使用抓手工具更加合适一些。

Snipaste_2020-05-12_03-50-39

下来我们对上面的现在做一个规律性的总结,方便日后更加敏捷的开发:

# 总结flex-direction的使用方法有四种
# flex-direction: row;            //水平且正序排布(位于左上角)
# flex-direction:column;          //纵向且正序排布(位于左上角)
# flex-direction: row-reverse;    //水平且倒序排布(位于右上角)
# flex-direction:column-reverse;  //纵向且倒序排布(位于左下角)
--------------------------------------------------------------------
#规律:对于view(特指容器),如果你不指定宽度,那么默认就是100%,但是高度比较特殊,默认是自适应的。
 

Justify-content属性

Justify-content属性是用于设置对齐方向的

justify-content属性定义了项目在主轴上的对齐方式。
-------------------------------------------------------------------
# flex-start(默认值): 左对齐
# flex-end: 右对齐
# center: 居中
# space-between: 两端对齐,项目之间的间隔都相等。
# space-around: 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
 

在使用Justify-content属性之前,我们需要知道的是Justify-content属性会受到flex-difection排序的影响。这是什么意思呢?

答:简单来说,当我们的色块处于水平正序的时候,才会按照上面的规则展现出效果。

A、水平正序

左上对齐

flex-start(默认值):左对齐

Snipaste_2020-05-12_04-10-00

右上对齐

flex-end:右对齐

Snipaste_2020-05-12_04-1023-00

居中对齐

center: 居中

Snipaste_2020-05-12_04-101223-00

两端对齐,间隔相同

space-between:两端对齐,项目之间的间隔都相等。

Snipaste_2020-05-12_04-10122233-00

中间间隔=边框间隔*2

space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

Snipaste_2020-05-12_04-22-17

B、纵向正序

左上对齐

flex-start(默认值):左上对齐

Snipaste_2020-05-12_04-26-09

左下对齐

flex-end:左下对齐

Snipaste_2020-05-12_04-26-10

居中对齐

center: 居中对齐

Snipaste_2020-05-12_04-26-0901

两端对齐,间隔相同

space-between:两端对齐,项目之间的间隔都相等。

Snipaste_2020-05-12_04-26-0903

中间间隔=边框间隔*2

space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

Snipaste_2020-05-12_04-26-0905

上面的正确其实挺容易明白的,基本上都是按照Justify-content的规则进行展示。但是如果我们按照倒序排布的话,那么就会反过来。最终的效果可以往下查看。

C、水平倒序

右上对齐

flex-start(默认值):右上对齐

Snipaste_2020-05-12_04-26-0909

你会发现在倒序的影响下,flex-start的展示效果和正序完全颠倒过来了。

左上对齐

flex-end:左上对齐

Snipaste_2020-05-12_04-26-11

居中对齐

center: 居中对齐

Snipaste_2020-05-12_04-26-13

两端对齐,间隔相同

space-between:两端对齐,项目之间的间隔都相等。

Snipaste_2020-05-12_04-26-16

中间间隔=边框间隔*2

space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

Snipaste_2020-05-12_04-26-111

D、纵向倒序

左下对齐

flex-start(默认值):左下对齐

Snipaste_2020-05-12_04-26-31

左上对齐

flex-end:左上对齐

Snipaste_2020-05-12_04-26-33

居中对齐

center: 居中对齐

Snipaste_2020-05-12_04-26-36

两端对齐,间隔相同

space-between:两端对齐,项目之间的间隔都相等。

Snipaste_2020-05-12_04-26-41

中间间隔=边框间隔*2

space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

Snipaste_2020-05-12_04-26-43

​ 如果说,现在我们希望色块不但能够垂直居中还能够水平居中(既处于正中间),那么请问需要怎么处理呢?通过上方的案例来看,Justify-content属性的设置,只能在一个方向上居中,要么只是垂直居中,要么水平居中,如果说我们现在要保持正中间,那么需要我们既能保持垂直居中,还能保持水平居中。那么为了解决这个问题,我们应该怎么做呢?为了解决这个问题,于是有了align-items属性

align-items属性

'align-items属性'是用来定义项目在'交叉轴上'如何对齐。
--------------------------------------------------------------
# flex-start: 交叉轴的起点对齐。
# flex-end: 交叉轴的终点对齐。
# center: 交叉轴的中点对齐。
# baseline: 项目的第一行文字的基线对齐。
# stretch(默认值): 如果项目未设置高度或设为auto,将占满整个容器的高度。
 

主轴和交叉轴

在使用align-items属性之前,我们先要搞清楚两个概念,那就是主轴交叉轴

请问如何弄清楚谁是主轴呢?谁又是交叉轴呢?

答:首先,我们需要清楚的一点是,在代码里面没有固定死谁是主轴,谁是交叉轴的,它是由程序员编写flex-direction属性的时候决定的。而不是在代码里面固定死哪个是主轴,哪个是交叉轴的。

也就是说,==谁是主轴,完全是由flex-direction属性的设定而决定。==

如果flex-direction设置为column,那么==column就是主轴,row就是交叉轴==;

# flex-direction:column;  那么column就是主轴,row就是交叉轴
 
Snipaste_2020-05-12_05-38-201
# 同理,如果说flex-direction设置为row ;  那么row就是主轴,column就是交叉轴
 
Snipaste_2020-05-12_05-381-20

那么请问知道了主轴交叉轴之后,为的是什么呢?

我们不妨看一下align-items属性有哪些?

Snipaste_2020-05-12_05-52-43

所以说区分出主轴交叉轴的目的是为了区分align-items属性justify-content属性

可能不是很容易理解,我这边给大家模拟一下这个场景。

我们先让色块都处于正中间。然后再去看align-items属性justify-content属性

Snipaste_2020-05-12_06-00-49

那么问题来了,知道了主轴交叉轴以后,如何区分两者的属性呢?

其实justify-content属性align-items属性对应的功能是对应的。如果我们知道了谁是主轴以后,我们就可以直接在justify-content属性上控制主轴的排列方向。

# justify-content   //控制着“主轴”方向、排布和对齐的方式
# align-items       //控制着“交叉轴”方向、排布和对齐的方式
 

为了进一步理解,我们不妨做一个案例进行讲解。

比如说,我们现在要求三个色块处于水平居中,但是在垂直方向向上对齐。换句话说就是让原有的色块往上移。那么需要怎么做呢?

Snipaste_2020-05-12_06-18-17

通过代码我们可以知道,这里的主轴是conlmn(也就是列方向)。往上移,也就是改变主轴的设置,也就是改变justify-content的设置。而align-wrap属性不需要改变,还是保持原来的居中即可

Snipaste_2020-05-12_05-38-201

具体的代码如下:

Snipaste_2020-05-12_06-29-27

​ 运行到这里的时候,我们会发现,相比较于Justify-content属性设置而言,align-items属性会多出两个参数设置,那就是baseline属性stretch属性;下面我们将重点讲解一下这两个属性的用法。

baseline

# baseline: 项目的第一行文字的基线对齐。
 

为了能够理解baseline属性,我们需要设置一些前提条件。我们这里将色块内的文字大小做了更改。

Snipaste_2020-05-12_07-23-55

那么此时我们将align-items设置为baseline,那么会发生什么样的变化呢?

Snipaste_2020-05-12_07-33-10

需要注意的是,这里面的细节之处:三个色块内部的文字的底部居然对齐了。

Snipaste_2020-05-12_07-37-50

总结:让项目的第一行文字的基线对齐。这就是baseline属性的作用

stretch

# stretch(默认值): 如果项目未设置高度或设为auto,将占满整个容器的高度。
 

主轴设置为列column的情况下,我们设置align-items:stretch;会呈现什么效果呢?

首先我们要想看align-items:stretch;的效果,有一个前提条件就是项目未设置高度

Snipaste_2020-05-12_07-03-16

那么此时我们将align-items设置为stretch后的效果如下。

Snipaste_2020-05-12_07-10-29
# align-items:stretch;
 

如果此刻,我们将主轴设置为水平方向。会发生什么呢?

Snipaste_2020-05-12_07-16-07

flex-wrap属性(控制“换行”)

默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

image-20200512075209562
它可能取三个值
# nowrap(默认):不换行。
# wrap:换行,第一行在上方。
# wrap-reverse:换行,第一行在下方。
 

nowrap(默认):不换行。

image-20200512075403992

wrap:换行,第一行在上方。

image-20200512075513003

wrap-reverse:换行,第一行在下方。

image-20200512075533235

上面这些是flex-wrap属性的使用方法和说明,下面我们针对这些属性进行模拟演示。

为了能够更好的理解上面的的参数意义,我们首先要做到的就是让一行承载不下所有的色块。

# 在iphone6的手机中宽度为:414px。
 
Snipaste_2020-05-12_08-00-22

因此我们需要将色块的宽的设置(414px除于3=138px)必须大于138px以后,色块才能在一行中容纳不下。

Snipaste_2020-05-12_08-05-07

我们不妨用抓取工具进行抓取看一下,你会发现色块会强行挤在一行内,即使不满足我们设置的宽度也要挤进去,那么如果是这样的话,色块内部的内容势必会挤变形。

Snipaste_2020-05-12_08-09-52

如果说,我们现在不想色块被积压变形的话,那么我们应该怎么办?

其实上面之所以会不换行,遇到色块之和大于手机宽度的话,及时被挤压也不换行。在代码中是这样设置的。

# flex-wrap: nowrap; // 不换行(默认设置)
 

因为是默认设置,所以如果不设置的话,那么默认就是不换行的

Snipaste_2020-05-12_08-18-47

那么此刻我们需要他换行的话,我们就可以这样设置

# flex-wrap: wrap; // 第一行在上方。
 
Snipaste_2020-05-12_08-21-38

我们通过抓取工具在看一下,你会发现,现在的色块宽度就正常了。

Snipaste_2020-05-12_08-23-13

到这里以后,我们不妨思考一下,为什么换行以后会空出一个空间出来。正常来说不应该是贴在一起换行的吗?请问这个是代码的错误吗?

答:其实不是的,这就是flex默认换行的特性。

那么如何解决换行出现一个空白区域这样的问题呢?

首先我们需要知道的是,下面两个距离是一致的。也就是说系统其实让色块3处于剩余的位置内,且让色块3的上面的距离和下面的距离处于平均的位置上。

Snipaste_2020-05-12_08-28-46

那么如果说我们需要将色块3位于色块1色块2的底部贴合。其实有个思路是:让距离A距离B都等于零,那么自然色块3就能贴合色块1色块2的底部了。

Snipaste_2020-05-12_08-38-18

于是我们将容器的高度设置为200px。

Snipaste_2020-05-12_08-45-15

其实这样我们就已经抛砖引玉了,其他的属性设置,可以在设置一下。看看里面的变化效果。

Flex布局的拓展

上面这些设置就是老师教学中的所有内容,如果说我们还要更加深入的了解flex布局的话,我们可以参照下面这些内容。

小程序Flex 布局教程:语法篇

Flex 布局教程:实例篇

本文地址:H5W3 » 微信小程序篇:Flex布局

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址