基本使用
容器属性
- flex-direction:row | row-reverse | column | column-reverse; 项目排列方向
- flex-wrap:nowrap | wrap | wrap-reverse; 轴线排不开如何换行
- flex-flow:flex-direction属性和flex-wrap属性的简写形式
- justify-content:flex-start | flex-end | center | space-between | space-around;左|右|居中|两端|均分
- align-items:flex-start | flex-end | center | baseline | stretch;交叉轴如何对齐
baseline
: 项目的第一行文字的基线对齐。stretch
(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
- align-content:定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
flex-start
:与交叉轴的起点对齐。flex-end
:与交叉轴的终点对齐。center:与交叉轴的中点对齐。
space-between``:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around``:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。
项目属性
**order**``:定义项目的排列顺序。数值越小,排列越靠前,默认为0。
**flex-grow**``:项目的放大比例,默认为0,即如果存在剩余空间,也不放大
**flex-shrink**``:项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。0不缩小,负值无效
**flex-basis**``:在分配多余空间之前,项目占据的主轴空间。默认值为auto,即项目的本来大小
**flex**``:flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。
auto (1 1 auto) 和 none (0 0 auto)
**align-self**``:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch
NOTE
flex-basis
指定了 flex 元素在主轴方向上的初始大小
Note: 当一个元素同时被设置了
flex-basis
(除值为auto
外) 和width
(或者在flex-direction: column
情况下设置了height
) ,flex-basis
具有更高的优先级.
优先级:content —> width —> flex-basis (limted by max|min-width)
当项目同时定义了min(max)-width,flex-basis失效,当同时定义了flex-basis和width,依赖于flex-basis
如果容器宽度不够,item宽度会缩小以撑满容器
2.flex-grow flex-shink
flex-grow:当容器宽度足够有剩余的时候,项目按照放大比例撑满
<div class="as-flex">
<div class="item-1 pink">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
<div class="item-1 lightblue">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
<div class="item-1 lightgray">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
</div>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.as-flex{
display: flex;
}
.item-1{
flex-grow: 1;
}
.pink{
background: pink;
}
.lightblue{
background: lightblue;
}
.lightgray{
background: lightgray
}
</style>
页面内容其实就是三个span标签中的内容,flex-grow的逻辑是对剩余空间分成。
当前的屏幕宽度为600px,三个span标签的长度分别为104px、104px、243.4px,
那么页面剩余空间为(600-104-104-243.4)=148.6px,根据分成的比例1:1:1(flex-grow对应的值),
可计算得到三个div标签的分得的剩余空间分别为49.533px(148.6/3)、49.533px、49.533px,
加上标签本来的长度则对应的三个div的长度分别为153.533px(104+49.533)、153.533px、292.933px。
页面选取对应的div,长度与计算完全吻合。同样的,如果flex-grow属性分别为1:1:2,
剩余空间会按照1:1:2的比例来分成,再加上div的内容长度,就是其总长度
<div class="as-flex">
<div class="item-1 pink">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
<div class="item-1 lightblue">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
<div class="item-2 lightgray">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
</div>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.as-flex{
display: flex;
}
.item-1{
flex-shrink: 1;
}
.item-2{
flex-shrink: 2;
}
.pink{
background: pink;
}
.lightblue{
background: lightblue;
}
.lightgray{
background: lightgray
}
</style>
三个div
标签本来的宽度都为104px
(span
标签的宽度),as-flex
对应的div
的宽度为300px
,很明显,空间不够了,需要大家挤一挤,怎么个挤发,就需要按照flex-shrink
的约定来让出自己的部分空间。例如,三个div
原来都需要占用104px
的空间,总共要占用312px
的空间,现在只有300px
,缺少12px
。按照flex-shrink
的约定,三个div
按照1:1:2
来分配缺少的12px
,三个div
分别让出3px
(12/(1+1+2)
)、3px
、6px
的空间,则最终三个div
的实际长度分别为101px
、101px
、98px
,这与浏览器中div
的实际长度相等。
同样的,如果有一个div
是固定宽度的话,三个div
的宽度如何计算呢?看如下的例子:
<div class="as-flex">
<div class="item-1 pink">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
<div class="item-2 lightblue">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
<div class="width208 lightgray">
<span>1 2 3 4 5 6 7 8 9</span>
</div>
</div>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.as-flex{
display: flex;
}
.item-1{
flex-shrink: 1;
}
.item-2{
flex-shrink: 2;
}
.width208{
width: 208px;
}
.pink{
background: pink;
}
.lightblue{
background: lightblue;
}
.lightgray{
background: lightgray
}
</style>
<div class="outer">
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</div>
.outer { width: 500px; display: flex; }
.outer div { height: 80px; }
.div1 { flex: 1 1 100px; background: red; }
.div2 { flex: 1 2 200px; background: yellow; }
.div3 { flex: 1 3 300px; background: green; }
500<600px(100+200+300)
先计算总权重TW = 100px 1(flex-shrink) + 200px 2(flex-shrink) + 300px *3(flex-shrink) = 1400px 也就是每个div的宽度乘以flex-shrink系数的总和。
每个div收缩的空间为:div的宽度 flex-shrink系数/ 总权重TW 需要收缩的总宽度(在我们的例子中是600px - 500px = 100px)
所以各div最后的宽度计算公式如下:
div1最后的宽度 = 100px - 1001/1400 100px = 92.86px
div2最后的宽度 = 200px - 2002/1400 100px = 171.42px
div3最后的宽度 = 300px - 3003/1400 100px = 235.72px
——————————————————————————
| | |
——————————————————————————
width:200px flex-basis:300px flex-grow:1
flex-grow:1
总宽 1000px
问:1. 每个item多宽?
200px 550px 250px
2.如果item3 flex-basis:300px,flex-shink分别是 1 2 3,总宽600px?
TW: 2001+3002+3003=1700
item1: 200-2001/1700*200
References:
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
https://www.zhangxinxu.com/wordpress/2020/10/css-flex-0-1-none/
https://juejin.cn/post/6844904016439148551
https://www.zhangxinxu.com/wordpress/2019/12/css-flex-deep/
https://zhuanlan.zhihu.com/p/354926684
29 CSS Flex排版:为什么垂直居中这么难?
https://www.ruanyifeng.com/blog/2015/07/flex-examples.html
https://zhuanlan.zhihu.com/p/47613256