一, 序
Hi, 大家好, 我是承香墨影!
最近在做小程序, 验证一些方向, 开发效率确实很快, 就是各种微信的审核有点费劲, 但是总归是有办法解决的.
想要开发一款小程序, 其实和我们正常写一款 App 类似, 你需要有精美的前端布局, 并且同时还需要处理和前端 UI 组件的交互以及它们背后的逻辑.
最近会分享一些关于小程序的内容(不保证, 想到哪里写到哪里), 今天先说说接触小程序第一步: 布局.
如果有前端经验的话, 小程序是非常容易上手的, 而对于新手, 第一步当然是阅读小程序的官方文档, 不过之后你马上就要面临布局的问题.
在小程序的开发框架中, 会使用 Flex 排版布局, 它可以帮助我们快速的在小程序中进行 UI 布局. 虽说 Flex 现在已经被主流浏览器所支持, 但是 flex 在一些低版本的浏览器上还有些许兼容的问题. 不过在小程序中, 这就不是我们需要考虑的了, 微信已经帮我们处理好了.
接下来我就以完整的小程序来做示例, 说说 flex 布局的那些事情. 话不多说, 言归正传.
二, 什么是 Flex
Flex 是 2009 年, W3C 提出的一种新的布局适配方案, 通过 Flex 布局, 可以简便, 完整, 响应式的实现各种页面布局. 经过这些年的发展, 已经得到了所有浏览器的支持, 基本上可以让我们放心使用.
Flex 布局是 Flexible Box 的缩写, 直译过来就是 "弹性盒子", 它也是基于 "盒子" 模型, 将 UI 切割成一个一个小的盒子, 来进行 UI 布局.
如果你不是在开发小程序, 而是想单纯的开发移动前端, 你也可以使用 Flex 布局. 虽然 Flex 已经被所有浏览器支持, 但是架不住有一些老旧的浏览器, 例如: IE 9, 也是存在不支持的情况的. 不过我们只是开发小程序, 就完全不用担心这一点.
三, Flex 如何使用
3.1 概述
Flex 的使用非常的简单, 你只需要将 display 设置为 flex 就可以了.
display 除了 flex 还有一些其他可选参数, 具体的你可以参见文档.
而在新手阶段, 暂时只需要关注两个参数:
block : 指定一个块级布局, 它其内的元素, 总是起一个新行来显示, 而微信小程序的很多视图容器组件, 默认的 displa 就是 block, 例如: view,scroll-view,swiper 等.
flex: 指定为 Flex 布局, 它可以在盒子内显示子元素.
举个例子, 看一下效果图:
在这里, 当不做特殊设置的时候, 默认为 display:block 的状态, 其内的每一个元素, 都另起一行去展示. display:flex 的话, 我们就可以自由设置其内元素的布局形式, 这里只是显示了 flex 默认的效果, 实际上我们还可以通过 Flex 提供的不同的属性, 进行更灵活的布局.
3.2 Flex 的方向轴
想要掌握 Flex 布局, 你的心中时刻都需要有一个方向轴的概念.
在 Flex 布局中, 天然存在两根方向轴: 主轴和交叉轴. 交叉轴在有些地方又被称为侧轴, 其实是一个概念.
在默认情况下, 主轴是沿着水平方向延伸, 而交叉轴则正好与主轴呈交叉状态.
但是这并非不可改变, 我们可以通过 flex-direction 属性, 来改变主轴的方向, 交叉轴的方向是相对于主轴存在的, 当我们改变主轴方向后, 交叉轴也被同时改变.
既然 Flex 布局也是通过一些属性来控制效果的, 和我们正常写一个移动 App 是一样的, 有一些属性是作用在父容器中的, 有一些是作用在其内的子元素上的.
接下来我们就来分开讲解, 这些 Flex 布局的时候, 你需要使用到的属性.
3.3 Flex 在父容器上的属性
在父容器上, 存在的属性有:
flex-direction: 指定主轴的方向.
flex-wrap: 指定超出父容器的时候, 子元素的排列样式.
flex-flow:flex-direaction 和 flex-wrap 两个属性的组合简写形式.
justify-content: 子元素在主轴的排列方向.
align-items: 子元素在交叉轴上的排列方向.
align-content: 多根轴线的对齐方式.
这几个, 除了 align-content 都是相对比较常用的属性. 接下来我们就一一介绍这些属性, 以及在小程序中的使用效果.
1) flex-direction
前面也提到, flex 布局有两条轴, 它们是交叉相对的, 分为主轴和交叉轴. 我们可以通过 flex-direction 来确定主轴的方向, 同时交叉轴的方向也被确定了.
在 flex 布局中, 除了横竖两个轴之外, 轴还有起始点 (start) 和结束点 (end) 的概念, 加载一起 flex-direction 有四个属性.
row: 默认值, 主轴水平方向, 起始点在左边.
row-reverse: 主轴水平方向, 起始点在右边.
column: 主轴垂直方向, 起始点在上边.
column-reverse: 主轴垂直方向, 起始点在下边.
这个虽然非常好理解, 但是我们依然在小程序中看看效果.
2)flex-wrap
flex-wrap 属性用来确定, 父容器内, 当单行已经无法包容所有子元素之后, 如何换行.
nowrap: 不换行, 此为默认值.
wrap: 超出单行的时候, 自然换行.
wrap-reverse: 超出单行的时候, 沿着底部翻转方向, 自然换行.
CSS 里就是有很多属性是带有 xxx-reverse 参数的, 大多数情况下我们也用不上, 不过还是了解一下没坏处.
虽然图片已经很清晰了, 从 flex-wrap:wrap 中, 可以看出 A,B,C 三个元素, 实际上宽度是不一致的.
一般在单纯的介绍 flex-wrap:wrap 属性的文章, 其实是会说将多余的部分切割在父布局之外.
我也盗个图, 看看别人教程里显示的效果.
实际上如果你在纯前端的环境中, 使用 flex-wrap:wrap 也确实是这个效果, 所以这并不是错误, 我理解这就是表现的差异.
但是在小程序中的表现并不是这样的, 它最终会根据你设置的子元素的宽度, 横向的等比进行缩放, 让它可以在当行内显示的下.
在这个例子中, C 块是宽度最宽的一个布局, 当我们增加 C 块的时候, 看看这样极端情况下, flex-wrap:nowrap 在小程序中的表现.
可以看到, 它会等比例压缩其内所有布局的宽度, 这是一点差异, 需要特别注意.
3)flex-flow
flex-flow 是前面两个属性 flex-direction 和 flex-wrap 的简写组合.
在 css 中, 很多属性都是一些属性的组合, 是存在这种写法的, 中间使用空格分割就可以了.
例如:
- .ele {
- flex-flow: row nowrap;
- }
这样就可以一次对两个属性进行设置, 并不冲突.
4)justify-content
justify-content 可以用来设置子元素, 在主轴方向上的对齐方式.
它有五个可选项:
flex-start: 默认值, 左对齐.
flex-end: 右对齐.
center: 居中.
space-between: 两端对齐, 元素之间等距.
space-around: 每个子元素间隔相等, 表现来看就是, 元素距离边框的距离, 是元素与元素距离的一半.
justify-content 基本上看描述就知道效果了, 不过 space-between 和 space-around 看似很像, 但是实际上也是有差异的, 我们看看最终运行的效果是最清晰的.
可以看到 space-around 是会保留左右的边距, 感觉就像是为每个元素都增加了一个左右的 margin 属性, 而 space-between 则只在子元素之间存在距离.
5)align-items
align-items 属性, 可以定义在交叉轴上, 子元素的对齐方式.
它也存在五个选择参数:
flex-start: 交叉轴的起点对齐.
flex-end: 交叉轴的终点对齐.
center: 交叉轴方向居中.
baseline: 子元素的第一个元素, 内容基线对齐.
stretch: 默认参数, 会在交叉轴上铺满父布局.
注意 align-items:stretch 和前面我们的属性描述是不符合的, 主要原因是它有两个限制.
父容器, 必须限定高度.
子元素, 必须没有指定高度, 宽还是高, 就取决于交叉轴的方向.
例如前面的代码, 我们根据这里的两个限制进行修改.
align-items 还有一点需要注意的参数是 baseline, 它是根据主轴方向, 第一个元素的内容为基准进行对齐, 我们把 A 块, 增加一个 margin-top 再来看看效果.
可以看到, 其他属性均有影响, 但是 baseline 的时候, 依然可以保持子元素基于内容对齐.
6)align-content
align-content 属性指定交叉轴上, 元素的对齐方式, 和 align-items 有点类似. 一般移动端的 UI 布局, 都是倾向于列表形式无限向下延伸, 所以 align-content 的用处其实不大.
但是当你需要做一个单页效果, 例如活动图, 就可以利用上 align-content 属性了.
align-content 有六个可选的属性:
stretch: 默认值, 拉伸占满交叉轴, 和 align-items 限制类似.
flex-start: 与交叉轴起点对齐.
flex-end: 与交叉轴终点对齐
center: 以交叉轴居中.
space-between: 与交叉轴两端对齐, 并且子元素保持间距相等.
space-around: 在交叉轴方向, 子元素与边距, 均保持相同距离.
其实我们理解了 align-items , 对于 align-content 就非常好理解了.
没什么好多说的, 直接上一个效果图看看.
四, Flex 的子容器属性
在 Flex 布局的设定中, 子元素有 6 个属性:
flex-grow: 子元素剩余空间的拉伸比例.
flex-shrink: 子元素超出空间, 反向对子元素的拉伸比例.
flex-basis: 设定子元素, 在不被拉伸情况下的原始比例.
flex: 前三个属性的集合属性.
order: 设定子元素, 显示的顺序.
align-self: 覆盖父容器设定的 align-items 属性, 来操作子元素对交叉轴的对齐效果.
其实真正常用的就这么些, 我们一个一个仔细分析, 保持之前的风格, 都会以小程序中, 真实的效果截图举例.
1. flex-grow 属性
flex-grow 属性, 可以定义子元素在父元素中的伸缩比例, 按照比例为子元素分配不同的空间大小.
请注意看这里给了两个例子, A 例子中, A,B,C 三个子元素的 flex-grow 分别设置为 1,2,3, 并且每个子元素的宽度, 设置为 5 rpx.
当设定了 flex-grow 之后, 其内的子元素不注意占满整个父容器, 就会按照 flex-grow 设定的比例, 分配子元素的空间, flex-grow 的数值越小, 占据的空间越小.
以这里的表现来看, flex-grow 从小到大占据父容器的空间.
而 B 例子, 我们将子元素的宽度 width 属性, 设置为 500rpx 之后, 明显一行已经不够放下 3 个子元素了. 这个时候 flex-grow 将不生效, 将会呈现等比例排列.
此属性想要生效, flex-wrap 必须设定为 nowrap, 意思是不允许换行, 所有和比例相关的属性, 都需要 nowrap 加持.
希望大家熟悉这样的举例方式, 后面的例子, 均会以这样的形式表示参数的设定.
width, 为子元素的宽度.
属性: 1,2,3 分别为不同的值.
2. flex-shrink 属性
flex-shrink 定义子元素, 在容器之外的空间, 呈比例反向缩放.
flex-shrink 既然是指定的超出父容器之外部分的缩放比例, 如果所有的子元素, 并不会超出父容器, 此属性将失效, 如 A 例子中的效果.
而在 B 例子中, 设定子元素宽度 width 为 500rpx, 超出父容器的部分, 将成比例反向控制子元素的大小.
在这里的表现, 就是 flex-shrink 生效的情况下, 数值越小, 占据的空间越大.
3. flex-basis 属性
flex-basis 用于定义子元素, 在不伸缩情况下的原始尺寸.
前面介绍的两个属性, 无论是 flex-grow 和 flex-shrink, 都会在不同的情况下, 改变子元素的缩放比例, 如果我们想设定子元素, 在不出发缩放的情况下, 原始的大小, 就可以使用 flex-basis.
从例子中可以看到, flex-basis 只在缩放不生效的时候, 它才会生效.
4. flex 属性
前面介绍的三个属性, 很多属性的效果其实是互斥的, 所以 Flex 布局还提供了一个组合属性 flex, 用于对 flex-grow , flex-shrink , flex-basis 三个属性的缩写整合, 默认值为 0 1 auto, 而后两个属性是可选属性, 也就是你不写后两个, 等效于你只设置了 flex-grow.
为了更方便, flex 属性还提供了两个快捷值: auto(1 1 auto) 和 none(0 0 auto).
效果很简单, 就不多说明了.
5. order 属性
order 可以控制子元素, 在父布局的排列顺序, 数值越小, 排列越靠前.
利用 order 我们可以不遵循 Flex 布局里, 对子容器的编写顺序, 都是可以通过 order 修改的.
6. align-self 属性
在上一篇文章中, 我们将了可以通过父容器的 align-items 属性, 改变交叉轴上, 子元素在交叉轴上的排列方向. 而如果其中有子元素对这样的方向排列不满意, 还可以自己通过 align-self 属性进行修改.
align-self 的默认值是 auto, 表示继承父容器的 align-items 属性, 如果没有父元素, 等同于 stretch.
align-self 和 align-items 类似, 有六个可选项.
auto: 听父容器的.
flex-start: 交叉轴的起点对齐.
flex-end: 交叉轴的终点对齐.
center: 交叉轴的上居中对齐.
baseline: 已第一行文字的基准对齐.
stretch: 默认, 未设置高度的情况下, 占满整个高度.
这里的例子中, B item 就使用 align-self 修改了对齐方式为 center , 呈现出来的效果, 就是一个对父容器, 在交叉轴上居中的效果, 自己管理自己.
五, 小结
到这里, 关于小程序中 Flex 布局的使用, 基本上就算是讲清楚了. 虽然前端布局有很多奇淫技巧, 但是利用这两篇文章中介绍的属性, 已经可以排列出精美的 UI 效果.
快来开始你的小程序开发之旅吧!
公众号后台回复成长成长, 将会得到我准备的学习资料, 也能回复加群, 一起学习进步; 你还能回复提问, 向我发起提问.