第二章:flex布局
简介
- flex布局(Flexible布局,弹性布局)是在小程序开发经常使用的布局方式
- 官方文档
- https://www.w3.org/TR/css-flexbox-1/
- https://www.w3.org/TR/css-align-3/
- W3C是一个组织,专门用于制定html、css规范的组织
- flex container与flex items的概念
- 开启了flex布局的元素叫 flex container
- 一旦一个元素使用了flex布局就叫它flex容器(flex container)
- flex container 里面的直接子元素叫做 flex items
- 开启了flex布局的元素叫 flex container
- 如何开启flex布局?
- 设置display属性为flex或者inline-flex 可以成为flex container
- flex:flex container以block-level (块级元素)形式存在
- inline-flex:flex container以inline-level(行内元素)形式存在 (更像是行内块级,因为可以设置width、height)
- 注意:块级、行内块级、行内标签之前的区别
-
代码举例:
//标签 <view class="texstView1">texstView1</view> <view class="texstView2">texstView2</view> //css样式 .texstView1 { background: red; //块级block-level形式存在 display: flex; } .texstView2 { background: gray; //行内inline-level形式存在 display: inline-flex; //设置宽高有效,更像是行内块级 //height: 100rpx; //width: 400rpx; }
- 设置display属性为flex或者inline-flex 可以成为flex container
- Flex兼容性问题
- PC端:由于flex现在没有IE低版本的支持,即不建议用flex做PC端界面开发
- 移动端:可以用flex,虽然国产的UC浏览器的安卓低版本不支持flex语法,但它支持flexbox写法
常用CSS属性
-
应用在 flex container 上的CSS属性
flex-flow flex-direction 设置主轴方向 flex-wrap justify-content align-items align-content
-
应用在flex items上的CSS属性
flex flex-grow flex-basis flex-shrink order align-self
flex 布局模型
- 1个flex container内部有2个 flex items
应用在 flex container 上的 CSS 属性
flex-direction
- flex items 默认都是沿着main axis(主轴)从main start开始往main end 方向排布
- flex-direction 决定了main axis 的方向,有4个取值
- row(默认值)、row-reverse、column、column-reverse
justify-content
- justify-content决定了flex items 在main axis上的对齐方式
- flex-start(默认值):与main start 对齐
- flex-end:与main end对齐
- center:居中对齐
- space-between:
- flex items 之间的距离相等
- 与main start、main end两端对齐
- space-evenly:
- flex items之间的距离相等
- flex items与main start、main end之间的距离等于flex items之间的距离
- space-around:
- flex items之间的距离相等
- flex items与main start、main end之间的距离是flex items之间距离的一半
align-items
- align-items决定了flex items在 cross axis上的对齐方式
- stretch(默认值): 当flex items在cross axis方向的size(width、height)为auto时,会自动拉伸至填充flex container
- flex-start: 与 cross start对齐
- flex-end:与 cross end 对齐
- center:居中对齐
- baseline: 与基准线对齐
- 跟字体有关,比如下图的foo字体,4个items的foo字体大小都是不同的
- 那4个item的foo字体的底部就是基线,让4个items的基线对齐。
- 注意:交叉轴只有2个方向,没有反方向!!!
- 无论主轴是row还是row-reverse,交叉轴都是从上到下
- 无论主轴是column还是column-reverse,交叉轴都是从左到右
flex-wrap
- flex-wrap决定了flex container是单行还是多行
- nowrap(默认):单行
- 内容过多压缩到容器中,不是剪掉
- wrap:多行
- wrap-reverse:多行(对比wrap,cross start与cross end相反)
- nowrap(默认):单行
flex-flow
- flex-flow是flex-direction
||
flex-wrap的简写- 比如 flex-flow: column wrap 等价于
- flex-direction: column
- flex-wrap: wrap
- 比如 flex-flow: row-reverse 等价于
- flex-direction: row-reverse
- flex-wrap: nowrap
- 比如 flex-flow: wrap 等价于
- flex-direction: row
- flex-wrap: wrap
- 比如 flex-flow: column wrap 等价于
align-content
- align-content决定了多行flex items在cross axis上的对齐方式,用法与justify-content类似
- stretch:(默认值)与align-items的stretch类似
- flex-start: 与cross start对齐
- flex-end:与 cross end对齐
- center:居中对齐
- space-between:
- flex items之间的距离相等
- 与cross start、cross end两端对齐
- space-evenly:
- flex items之间的距离相等
- flex items与cross start、cross end之间的距离等于flex items之间的距离
- space-around:
- flex items之间的距离相等
- flex items与cross start、cross end之间的距离是flex items之间距离的一半
- 注意:如果设置了该属性,就不要设置单行对齐属性align-items,否则会有冲突
应用在 flex items 上的 CSS 属性
order
- order决定了flex items的排布顺序
- 可以设置任意整数(正整数、负整数、0),值越小就越排在前面
- 默认值是0
align-self
- flex items可以通过align-self覆盖flex container设置的align-items
- auto(默认值): 遵从flex container的align-items设置
- stretch、flex-start、flex-end、center、baseline,效果跟align-items一致
flex-grow
- flex-grow决定了flex items如何扩展
- 可以设置任意非负数字(正小数、正整数、0),默认值是0
- 当flex container在main axis方向上有剩余size时,flex-grow属性才会有效
- 就是说当主轴方向上有多余的空间时,可以通过给item设置flex-grow,使该item在主轴方向上的size扩展不同的比例来瓜分剩余的空间。
- 如果所有flex items的flex-grow总和sum超过1,每个flex item扩展的size为
- (flex container的剩余size)*flex-grow/sum
- sum大于1,items扩展会占满主轴剩余的空间
- 如果所有flex items的flex-grow总和sum不超过1,每个flex item扩展的size为
- (flex container的剩余size)*flex-grow
- 注意:sum小于1,items扩展不会占满主轴剩余的空间
- flex item扩展后的最终size不能超过max-width\max-height
- item有2个属性:max-width\max-height,一旦设置,即使扩展也不会超过该值。
flex-shrink
- flex-shrink决定了flex items如何收缩
- 可以设置任意非负数字(正小数、正整数、0),默认值是1
- 当flex items在main axis方向上超过了flex container的size,flex-shrink属性才会有效
- 就是说当主轴方向上所有的item的size之和大于父元素的size时,可以通过给item设置flex-shrink,使该item在主轴方向上的size收缩不同的比例来瓜分超出父元素的空间。
- 如果所有flex items的flex-shrink总和超过1,每个flex item收缩的size为
- (flex items超出flex container的size)*收缩比例/所有flex items的
收缩比例
之和 - flex-shrink总和超过1,items的收缩会将超出父元素的空间收缩完,即items不会超出父元素
- (flex items超出flex container的size)*收缩比例/所有flex items的
- 如果所有flex items的flex-shrink总和sum不超过1,每个flex item收缩的size为
- (flex items超出flex container的size * sum) *收缩比例/所有flex items的收缩比例之和
- flex-shrink总和小于1,items的收缩不会将超出父元素的空间收缩完,即items会超出父元素
- 注意:这个sum指的是所有items的flex-shrink之和
- 收缩比例 = flex-shrink * flex item的base size
- base size 就是 flex item 放入flex container之前的size
-
注意:这里的收缩比例可不是flex-shrink,跟扩展比例不一样,扩展直接是flex-grow !!!
背景: 有6个items,主轴为row,父元素宽度为500 每个tiem的宽度为110、120、130、140、150、160 , flex-shrink为:1、2、3、4、5、6 超出空间: 110+120+130+140+150+160 - 500 = 310; 注意:收缩比例不是flex-shrink,跟扩展比例不一样!!! 收缩比例 = flex-shrink * item的主轴方向size item1收缩比例 = 110 *1; ... item6的收缩比例= 160 *6; ---------sum>1---------- item1的收缩size为: 310*(110*1)/(110*1+120*2+...160*6) ... item6的收缩size为: 310*(160*6)/(110*1+120*2+...160*6) --------sum<1---------- 如果flex-shrink为:0.1、0.1、0.1、0.1、0.1、0.1 则flex-shrink之和sum为0.6<1 item1的收缩size为: 310*0.6*(110*0.1)/(110*0.1+120*0.1+...160*0.1) ... item6的收缩size为: 310*0.6*(160*0.1)/(110*0.1+120*0.1+...160*0.1)
- flex item收缩后的最终size不能小于min-width\min-height
- item有2个属性:min-width\min-height,一旦设置,即使扩展也不会小于该值。
flex-basis
- flex-basis用来设置flex items在main axis方向上的base size(如果主轴为row,那么这个base size就是width)
- auto(默认值)
- content:取决于内容本身的size
- 设置固定值比如:100px
- 决定flex items最终base size的因素,从优先级高到低(就是说item可以设置各种size,但是有优先级)
- max-width\max-height\min-width\min-height
- flex-basis
- width\height
- 内容本身的size
flex
- flex是flex-grow flex-shrink ?
||
flex-basis 的简写- 默认值是 0 1 auto
- none:0 0 auto
?
指的是flex-shrink 可有可无,即:0 auto
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container{
border: 1px solid #000000;
width: 500px;
height: 500px;
margin-left: 20px;
margin-top: 20px;
/* 开启flex布局 */
display: flex;
/* 设置主轴方向:row、 row-reverse、column、column-reverse */
flex-direction: row;
/* 设置主轴方向对齐方式 flex-start、flex-end、center、space-between、space-evenly、space-around*/
/* justify-content: center; */
/* 设置交叉轴的对齐方式:stretch(默认)、flex-start、flex-end、center、center*/
align-items: center;
/* nowrap(默认)、wrap、wrap-reverse*/
/* flex-wrap: wrap; */
/* 多行items在cross轴上的对齐方式:stretch、flex-start、flex-end、center、space-between、space-evenly、space-around */
/* align-content: stretch; */
}
.item{
/* 如果size为auto,那么就会是stretch */
width: 100px;
height: 100px;
/* width: auto;
height: auto; */
font-size: 50px;
color: white;
/* 内容居中 */
text-align: center;
line-height: 80px;
}
.item:nth-of-type(1){
background-color: red;
/* flex-grow: 1; */
width: 110px;
flex-shrink: 1;
}
.item:nth-of-type(2){
background-color: green;
/* 决定了flex items的排布顺序,越小排在越前面 */
/* order: 1; */
width: 120px;
flex-shrink: 2;
}
.item:nth-of-type(3){
background-color: blue;
/* 当前item覆盖掉父元素的align-items设置,默认值:auto,遵从父元素的lign-items设置 */
/* align-self: flex-start; */
width: 130px;
flex-shrink: 3;
}
.item:nth-of-type(4){
background-color: yellow;
width: 140px;
flex-shrink: 4;
}
.item:nth-of-type(5){
background-color: grey;
width: 150px;
flex-shrink: 5;
}
.item:nth-of-type(6){
background-color: purple;
flex-shrink: 6;
}
/* .item:nth-of-type(7){
background-color: rgb(0, 255, 0);
} */
/*
背景:
有6个items,主轴为row,父元素宽度为500
每个tiem的宽度为110、120、130、140、150、160 , flex-shrink为:1、2、3、4、5、6
超出空间: 110+120+130+140+150+160 - 500 = 310;
注意:收缩比例不是flex-shrink,跟扩展比例不一样!!!
收缩比例 = flex-shrink * item的主轴方向size
item1收缩比例 = 110 *1;
...
item6的收缩比例= 160 *6;
----------
item1的收缩size为: 310*(110*1)/(110*1+120*2+...160*6)
...
item6的收缩size为: 310*(110*6)/(110*1+120*2+...160*6)
*/
</style>
</head>
<body>
<!-- div>div.item*3 :一个div里面有4个div子元素 -->
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<!-- <div class="item">7</div> -->
</div>
</body>
</html>