? 关于 Flex,很多优秀的前辈已经总结过了,比如:阮一峰的《Flex 布局教程:语法篇》、知乎林东洲的《30 分钟学会 Flex 布局》等等。他们主要是基于网页的,小辈斗胆笔耕一篇倾向于 “微信小程序” 的 Flex 博客。
微信小程序开发 🌲
上一篇文章链接: 微信小程序学习笔记③——wxml+wxss+js基础入门[样例+解析]
下一篇文章链接: 🚧 🚧 …
一、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 (默认值) | 主轴为水平方向,起点在左端 | row-reverse | 主轴为水平方向,起点在右端 | column | 主轴为垂直方向,起点在上沿 | column-reverse | 主轴为垂直方向,起点在下沿 |
4.2 flex-wrap 属性
● 默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap 属性:定义如果一条轴线排不下,如何换行。它常用的有 3 个选项。
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
}
选项 | 功能 | 演示图 |
---|
nowrap (默认值) | 不换行 | 下图中红色方块的排列方式 | wrap | 换行,第一行在上方 | 下图中黄色方块的排列方式 | wrap-reverse | 换行,第一行在下方 | 下图中蓝色方块的排列方式 |
4.3 flex-flow 属性
● flex-flow 属性:是 flex-direction 属性和 flex-wrap 属性的简写形式,默认值为 row nowrap 。
.box{
flex-flow: <flex-direction:有四种> <flex-wrap:有三种>;
}
样例:
.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;
}
选项 | 功能 |
---|
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;
}
选项 | 功能 |
---|
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;
}
选项 | 功能 |
---|
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>;
}
5.2 flex-grow 属性
● flex-grow 属性:定义项目的放大比例,默认为0 ,即如果存在剩余空间,也不放大。
.item {
flex-grow: <number>;
}
◆ 说明:如果所有项目的 flex-grow 属性都为1 ,则它们将等分剩余空间(如果有的话)。如果一个项目的 flex-grow 属性为2 ,其他项目都为1 ,则前者占据的剩余空间将比其他项多一倍。如上图的第二个样例。
5.3 flex-shrink 属性
● flex-shrink 属性:定义了项目的缩小比例,默认为1 ,即如果空间不足,该项目将缩小。【下图中,中间个项目的 flex-shrink 为 0 ,其他两个为 1 】
.item {
flex-shrink: <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>;
}
◆ 说明:它可以设为跟 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;
}
选项 | 功能 |
---|
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%;
height: 40%;
margin-left: 5px;
margin-right: 5px;
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;
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 {
flex-direction: row;
justify-content: space-between;
}
.three_1 {
flex-direction: row-reverse;
}
.three_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基础入门[样例+解析]
下一篇文章链接: 🚧 🚧 …
?? ??
|