微信小程序学习笔记④——Flex布局[实战样例之画骰子]
关键词:微信小程序、Flex、Flex 容器的属性【flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content】、项目的属性【order、flex-grow、flex-shrink、flex-basis、flex、align-self】、样例画骰子。
✅ 关于 Flex,很多优秀的前辈已经总结过了,比如:阮一峰的《Flex 布局教程:语法篇》、知乎林东洲的《30 分钟学会 Flex 布局》等等。他们主要是基于网页的,小辈斗胆笔耕一篇倾向于 “微信小程序” 的 Flex 博客。
文章目录
微信小程序开发 🌲
上一篇文章链接: 微信小程序学习笔记③——wxml+wxss+js基础入门[样例+解析]
下一篇文章链接: 微信小程序(5)——如何制作好看的表格
一、Flex 概述
● 为什么要学 “布局”?
因为后面设计微信小程序的展示界面时,若没有一个良好的 “底层页面摆放逻辑”,那么我们的小程序很可能来实用过程中出现 “内容显示不全”、“图片变形或错位”、“表格错位”、“文本框重叠” 等莫名其妙的 Bug。学 “布局” 不是一个需要我们去敲它的底层逻辑,而是去学如何良好的使用它。
● 为什么要学 “Flex布局”?原因如下:
2009年,W3C(万维网联盟,全称World Wide Web Consortium)提出了一种新的方案——“Flex布局”,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。Flex布局将成为未来布局的首选方案。
◆ 说明:以上是主流浏览器支持的力度。最下面的版本是最新版本,可以发现,几乎全部都是 “Supported”。
● Flex 简介:全称为 “Flexible Box Layout”,即 “弹性盒布局”,旨在提供一种更有效的方式来布局、对齐和分配容器中项目之间的空间,即使它们的大小未知或动态变化。
● Flex 布局背后的主要思想:是让容器能够改变其项目的宽度/高度(或顺序)以最好地填充可用空间(主要是为了适应各种显示设备和屏幕尺寸),以防止显示不完整或溢出。
● “Flex 布局”与 “常规布局” 的对比:与常规布局(基于垂直的块和基于水平的内联)相反,弹性盒布局与方向无关。虽然这些适用于页面,但它们缺乏灵活性来支持大型或复杂的应用程序(尤其是在涉及方向更改、调整大小、拉伸、收缩等方面 → 比如说在拉伸缩小页面时,页面显示的东西也跟着 “弹性地” 变化,你可以试试拉伸这个网站:《A Complete Guide to Flexbox》)。
● 注意: Flexbox 布局最适合应用程序的组件和小规模布局,而 Grid 布局适用于更大规模的布局。
● 学习 Flex 的官方文章:《A Complete Guide to Flexbox》、《A Visual Guide to CSS3 Flexbox Properties》
二、基础知识和术语
● 采用 Flex 布局的元素,称为『Flex容器(flex container)』,简称 ”容器”。它的所有子元素自动成为容器成员,称为『Flex项目(flex item)』,简称”项目”。
◆ 说明:
① 容器默认存在两根轴:水平的『主轴(main axis)』和垂直的『交叉轴(cross axis)』。【注,我们可以通过修改使垂直方向变为主轴,水平方向变为交叉轴,后面会讲】
② 主轴与左右边框的交叉点,分别叫作『主轴开始处(main start)』、『主轴结束处(main end)』。
③ 交叉轴与左右边框的交叉点,分别叫作『交叉轴开始处(cross start)』、『交叉轴结束处(cross end)』。
④ 项目默认沿主轴排列。单个项目占据的主轴空间【注,这里的空间是一维的,即“长度空间”】叫作『占主轴尺寸(main size)』,占据的交叉轴空间叫做『占交叉轴尺寸(cross size)』。
三、Flex 容器初了解
● 任何一个容器都可以指定为 Flex 布局。样例如下:
▼ WXML代码如下:
<image src="./Images_Flex/Flex项目1.png" style="width: 60px;height: 60px;"></image>
<image src="./Images_Flex/Flex项目2.png" style="width: 60px;height: 60px;"></image>
<image src="./Images_Flex/Flex项目3.png" style="width: 60px;height: 60px;"></image>
<image src="./Images_Flex/Flex项目4.png" style="width: 60px;height: 60px;"></image>
<image src="./Images_Flex/Flex项目5.png" style="width: 60px;height: 60px;"></image>
<view class="MyContainer">
<image src="./Images_Flex/Flex项目1.png" style="width: 60px;height: 60px;"></image>
<image src="./Images_Flex/Flex项目2.png" style="width: 60px;height: 60px;"></image>
<image src="./Images_Flex/Flex项目3.png" style="width: 60px;height: 60px;"></image>
<image src="./Images_Flex/Flex项目4.png" style="width: 60px;height: 60px;"></image>
<image src="./Images_Flex/Flex项目5.png" style="width: 60px;height: 60px;"></image>
</view>
▼ WXSS代码如下:
.MyContainer_1 {
display: flex;
justify-content: space-around;
}
◆ 代码说明:
① 引入图片用的是 “image
” 标签,src
指向图片的存储路径,style
和 class
的功能类似,只不过可以直接在标签项里面写。
② px
是像素的意思,是一中计量单位,60px
表示占电脑屏幕的 60
个像素点。
③ .wxml
代码中的第二段中出现了 “嵌套”,这是笔者写 “微信小程序学习笔记” 以来第一次出现。可以理解为内层的标签『项目』会包含在它外层的标签『项目』的里面。
④ container
是一个 WXSS 里面内嵌的一个 “封装好的选择器”,我们不用它,用自己写的。
⑤ display
是该选择器里面的一个( 布局)属性。
⑥ 项目默认沿主轴排列。
● 图片存储情况和运行结果:
◆ 说明:左边演示框的上面一堆是普通的摆放,下面的是 flex
布局。为什么为这样子摆放,是 “justify-content: space-around;
” 起的作用,后面会学到。【justify-content: space-around;
→ 每个项目两侧的间隔相等。且项目之间的间隔比项目与边框的间隔大一倍】
四、Flex 容器的属性
● Flex 容器常用的有 6
个属性:flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content。接下来将依次对其进行学习。并在文末进行实践运用。
4.1 flex-direction 属性
● flex-direction
属性:决定主轴的方向(即项目的排列方向)。它常用的有 4
个选项。
.box {
flex-direction: row; /* 或 row-reverse 或 column 或 column-reverse; */
}
选项 | 功能 |
---|---|
row (默认值) | 主轴为水平方向,起点在左端 |
row-reverse | 主轴为水平方向,起点在右端 |
column | 主轴为垂直方向,起点在上沿 |
column-reverse | 主轴为垂直方向,起点在下沿 |
4.2 flex-wrap 属性
● 默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap
属性:定义如果一条轴线排不下,如何换行。它常用的有 3
个选项。
.box{
flex-wrap: nowrap | wrap | wrap-reverse; /* 这样写只是为了方便展示, WXSS 没有这样的语法*/
}
选项 | 功能 | 演示图 |
---|---|---|
nowrap (默认值) | 不换行 | 下图中红色方块的排列方式 |
wrap | 换行,第一行在上方 | 下图中黄色方块的排列方式 |
wrap-reverse | 换行,第一行在下方 | 下图中蓝色方块的排列方式 |
4.3 flex-flow 属性
● flex-flow
属性:是 flex-direction
属性和 flex-wrap
属性的简写形式,默认值为 row nowrap
。
.box{
flex-flow: <flex-direction:有四种> <flex-wrap:有三种>; /* 这样写只是为了方便展示, WXSS 没有这样的语法*/
}
样例:
.box{
flex-flow: row nowrap;
}
4.4 justify-content 属性
● justify-content
属性:定义了项目在『主轴(main axis)』上的对齐方式。它常用的有 6
个选项。
.box{
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
/* 这样写只是为了方便展示, WXSS 没有这样的语法*/
}
选项 | 功能 |
---|---|
flex-start (默认值) | 左对齐 |
flex-end | 右对齐 |
center | 居中 |
space-between | 两端对齐,项目之间的间隔都相等 |
space-around | 每个项目两侧的间隔相等。且项目之间的间隔比项目与边框的间隔大一倍 |
space-evenly | 每个项目两侧的间隔相等。且项目之间的间隔与项目与边框的间隔一样大 |
4.5 align-items 属性
● align-items
属性:定义项目在『交叉轴(cross axis)』上如何对齐。它常用的有 5
个选项。【具体对齐方式与轴的方向有关。下面的演示图一律假设主轴为从左到右,交叉轴为从上到下】
.box{
align-items: flex-start | flex-end | center | baseline | stretch;
/* 这样写只是为了方便展示, WXSS 没有这样的语法*/
}
选项 | 功能 |
---|---|
flex-start | 交叉轴的起点对齐 |
flex-end | 交叉轴的终点对齐 |
center | 交叉轴的中点对齐 |
baseline | 项目的第一行文字的基线对齐 |
stretch (默认值) | 如果项目未设置高度或设为auto,将占满整个容器的高度 |
4.6 align-content 属性
● align-content
属性:定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。它常用的有 6
个选项。【具体对齐方式与轴的方向有关。下面的演示图一律假设主轴为从左到右,交叉轴为从上到下】
.box{
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
/* 这样写只是为了方便展示, WXSS 没有这样的语法*/
}
选项 | 功能 |
---|---|
flex-start | 与交叉轴的起点对齐 |
flex-end | 与交叉轴的终点对齐 |
center | 与交叉轴的中点对齐 |
space-between | 与交叉轴两端对齐,轴线之间的间隔平均分布 |
space-around | 每根轴线两侧的间隔都相等,且轴线之间的间隔比轴线与边框的间隔大一倍 |
stretch (默认值) | 轴线伸展(即项目拉伸)以占用剩余空间 |
五、项目的属性
● 前面把 “容器” 的属性讲完了,接下来讲 “容器” 里面的 “项目”。
● Flex 项目常用的有 6
个属性:order、flex-grow、flex-shrink、flex-basis、flex、align-self。
5.1 order 属性
● order
属性:定义项目的排列顺序。数值越小,排列越靠前,默认为0
。
.item {
order: <integer>; /* <integer> 即是我们需要写的数字*/
}
5.2 flex-grow 属性
● flex-grow
属性:定义项目的放大比例,默认为0
,即如果存在剩余空间,也不放大。
.item {
flex-grow: <number>; /* <number> 即是我们需要编写的数字*/
}
◆ 说明:如果所有项目的 flex-grow
属性都为1
,则它们将等分剩余空间(如果有的话)。如果一个项目的 flex-grow
属性为2
,其他项目都为1
,则前者占据的剩余空间将比其他项多一倍。如上图的第二个样例。
5.3 flex-shrink 属性
● flex-shrink
属性:定义了项目的缩小比例,默认为1
,即如果空间不足,该项目将缩小。【下图中,中间个项目的 flex-shrink
为 0
,其他两个为 1
】
.item {
flex-shrink: <number>; /* <number> 即是我们需要编写的数字*/
}
◆ 说明:
① 如果所有项目的 flex-shrink
属性都为1
,当空间不足时,都将等比例缩小。
② 如果这时存在一个项目的 flex-shrink
属性为0
,其他项目都为1
,则空间不足时,前者不缩小,后者全部等比例缩小。
③ 负值对该属性无效。
5.4 flex-basis 属性
● flex-basis
属性:定义了在分配多余空间之前,项目占据的『占主轴尺寸(main size)』。它的默认值为 auto
,即项目的本来大小。但如果设置了 flex-basis
,权重会比 width
属性高,因此会覆盖 widtn
属性。(假设主轴方向为 width
方向)
.item {
flex-basis: <length>; /* <length> 即是我们需要编写的数字*/
}
◆ 说明:它可以设为跟 width
或 height
属性一样的值(比如350px
),则项目将占据固定空间。
5.5 flex 属性
● flex
属性:是 flex-grow
、flex-shrink
和 flex-basis
的简写,默认值为 0 1 auto
。后两个属性可选。
.item {
flex: auto | none | [ <'flex-grow'> <'flex-shrink'> <'flex-basis'> ]
}
● 该属性有两个快捷值:auto
(1 1 auto) 和 none
(0 0 auto)。
◆ 说明:建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
5.6 align-self 属性
● align-self
属性:允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items
属性。默认值为 auto
,表示继承父元素的 align-items
属性,如果没有父元素,则等同于 stretch
。它常用的有 6
个选项。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
/* 这样写只是为了方便展示, WXSS 没有这样的语法*/
}
选项 | 功能 |
---|---|
auto (默认值) | 表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch |
flex-start | 交叉轴的起点对齐 |
flex-end | 交叉轴的终点对齐 |
center | 交叉轴的中点对齐 |
baseline | 项目的第一行文字的基线对齐 |
stretch | 如果项目未设置高度或设为auto,将占满整个容器的高度 |
六、实战样例 —— 画骰子⭐️⭐️
● 光说不练假把式,又说又练真把式!
● 设计要求:用一个 “容器” 装 6
个骰子,每个骰子显示一个面。
● WXML代码如下:
<view class="MyContianer">
<!-- 一点 -->
<view class="square">
<view class="null_paral">
<view class="null_Point"></view>
</view>
<view class="second_1">
<view class="Point"></view>
</view>
<view class="null_paral">
<view class="null_Point"></view>
</view>
</view>
<!-- 两点 -->
<view class="square">
<view class="first_1">
<view class="Point"></view>
</view>
<view class="null_paral">
<view class="null_Point"></view>
</view>
<view class="three_1">
<view class="Point"></view>
</view>
</view>
<!-- 三点 -->
<view class="square">
<view class="first_2">
<view class="Point"></view>
</view>
<view class="second_1">
<view class="Point"></view>
</view>
<view class="three_1">
<view class="Point"></view>
</view>
</view>
<!-- 四点 -->
<view class="square">
<view class="first_2">
<view class="Point"></view>
<view class="Point"></view>
</view>
<view class="null_paral">
<view class="null_Point"></view>
</view>
<view class="three_2">
<view class="Point"></view>
<view class="Point"></view>
</view>
</view>
<!-- 五点 -->
<view class="square">
<view class="first_2">
<view class="Point"></view>
<view class="Point"></view>
</view>
<view class="second_1">
<view class="Point"></view>
</view>
<view class="three_2">
<view class="Point"></view>
<view class="Point"></view>
</view>
</view>
<!-- 六点 -->
<view class="square">
<view class="first_2">
<view class="Point"></view>
<view class="Point"></view>
</view>
<view class="second_2">
<view class="Point"></view>
<view class="Point"></view>
</view>
<view class="three_2">
<view class="Point"></view>
<view class="Point"></view>
</view>
</view>
</view>
◆ 代码说明:
① 我的设计方案是:最外层(第1
层)一个大容器,flex
布局,且可换行。第2
层是六个骰子(即“小容器”)。第3
层是每个骰子里面的 “上、中、下” 的三个 “隐形的长方型框框”。最后一层(第4
层)是画 “点” 的『view 组件』。
② 我设计 “空行” 的方法是:在那个 “隐形的长方型框框” 塞一个和背景(黑色)颜色一样的骰子。
③ first_1
的意思是:first
行存在 1
个 “点” 的情况。
● WXSS代码如下:
.MyContianer {
margin-top:50px;
background-color: #e1e7e9;
border-left: 2px solid black;
border-right: 2px solid black;
border-top: 2px solid black;
border-bottom: 2px solid black;
height: 200px;
width: auto;
display: flex;
flex-wrap: wrap;
justify-content: space-around; /* 主轴 */
align-items: center; /* 交叉轴(默认是竖轴)居中 */
}
.square {
background-color: rgb(0, 0, 0); /* 骰子底色*/
width: 20%; /* 容器 width 的 20% */
height: 40%; /* 容器 height 的 20% */
margin-left: 5px; /* 外边距 */
margin-right: 5px;
/* 使用 flex 布局 */
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.null_paral, .first_1, .first_2, .second_1, .second_2, .three_1 ,.three_2 { /* 共有的属性*/
padding: 3px; /* 间距 */
display: flex; /* 使用flex布局 */
align-items: center; /* 交叉轴(默认是竖轴)居中 */
}
.null_paral {
flex-direction: row; /* 从左到右排列 */
justify-content: space-between; /* 两端对齐,项目之间的间隔都相等 */
}
.first_1 {
flex-direction: row; /* 从左到右排列 */
}
.first_2 {
flex-direction: row; /* 从左到右排列 */
justify-content: space-between; /* 两端对齐,项目之间的间隔都相等 */
}
.second_1 {
flex-direction: row; /* 从左到右排列 */
justify-content: center; /* 水平居中 */
}
.second_2 { /* 和 first_2 一样 */
flex-direction: row; /* 从左到右排列 */
justify-content: space-between; /* 两端对齐,项目之间的间隔都相等 */
}
.three_1 {
flex-direction: row-reverse; /* 从右到左排列 */
}
.three_2 { /* 和 first_2 一样 */
flex-direction: row; /* 从左到右排列 */
justify-content: space-between; /* 两端对齐,项目之间的间隔都相等 */
}
.Point { /* 白色的点 */
display: block;
height: 20px;
width: 20px;
background-color: #ffffff;
border-radius: 50%;
}
.null_Point { /* “隐藏”的点 */
display: block;
height: 20px;
width: 20px;
background-color: black;
border-radius: 50%;
}
◆ 代码说明:我觉得 .MyContianer{}
中的 flex-direction
应该设置为 row
才对,但是若这样设计,骰子的 “点” 就会很奇怪地排列,设置为 column
就没事。难道微信小程序有啥隐藏的 Bug?
● 运行结果:
七、参考附录
[1] 《Flex 布局语法教程》
[2] 《A Complete Guide to Flexbox》
[3] 《最详细完整的flex弹性布局》
[4] 《30 分钟学会 Flex 布局》,作者:林东洲
[5] 《Flex 布局教程:语法篇》,作者:阮一峰
[6] 《一篇文章弄懂flex布局》
[7] 《A Visual Guide to CSS3 Flexbox Properties》
[8] 《微信小程序开发之七 —— Flex、Grid与List布局》
[9]《微信小程序开发指南》
上一篇文章链接: 微信小程序学习笔记③——wxml+wxss+js基础入门[样例+解析]
下一篇文章链接: 微信小程序(5)——如何制作好看的表格
⭐️ ⭐️
更多推荐
所有评论(0)