基本使用

容器属性

  • 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:当容器宽度足够有剩余的时候,项目按照放大比例撑满

  1. <div class="as-flex">
  2. <div class="item-1 pink">
  3. <span>1 2 3 4 5 6 7 8 9</span>
  4. </div>
  5. <div class="item-1 lightblue">
  6. <span>1 2 3 4 5 6 7 8 9</span>
  7. </div>
  8. <div class="item-1 lightgray">
  9. <span>1 2 3 4 5 6 7 8 9</span>
  10. </div>
  11. </div>
  12. <style type="text/css">
  13. *{
  14. margin: 0;
  15. padding: 0;
  16. }
  17. .as-flex{
  18. display: flex;
  19. }
  20. .item-1{
  21. flex-grow: 1;
  22. }
  23. .pink{
  24. background: pink;
  25. }
  26. .lightblue{
  27. background: lightblue;
  28. }
  29. .lightgray{
  30. background: lightgray
  31. }
  32. </style>
  33. 页面内容其实就是三个span标签中的内容,flex-grow的逻辑是对剩余空间分成。
  34. 当前的屏幕宽度为600px,三个span标签的长度分别为104px、104px、243.4px,
  35. 那么页面剩余空间为(600-104-104-243.4)=148.6px,根据分成的比例1:1:1(flex-grow对应的值),
  36. 可计算得到三个div标签的分得的剩余空间分别为49.533px(148.6/3)、49.533px、49.533px,
  37. 加上标签本来的长度则对应的三个div的长度分别为153.533px(104+49.533)、153.533px、292.933px。
  38. 页面选取对应的div,长度与计算完全吻合。同样的,如果flex-grow属性分别为1:1:2,
  39. 剩余空间会按照1:1:2的比例来分成,再加上div的内容长度,就是其总长度
  1. <div class="as-flex">
  2. <div class="item-1 pink">
  3. <span>1 2 3 4 5 6 7 8 9</span>
  4. </div>
  5. <div class="item-1 lightblue">
  6. <span>1 2 3 4 5 6 7 8 9</span>
  7. </div>
  8. <div class="item-2 lightgray">
  9. <span>1 2 3 4 5 6 7 8 9</span>
  10. </div>
  11. </div>
  12. <style type="text/css">
  13. *{
  14. margin: 0;
  15. padding: 0;
  16. }
  17. .as-flex{
  18. display: flex;
  19. }
  20. .item-1{
  21. flex-shrink: 1;
  22. }
  23. .item-2{
  24. flex-shrink: 2;
  25. }
  26. .pink{
  27. background: pink;
  28. }
  29. .lightblue{
  30. background: lightblue;
  31. }
  32. .lightgray{
  33. background: lightgray
  34. }
  35. </style>

三个div标签本来的宽度都为104pxspan标签的宽度),as-flex对应的div的宽度为300px,很明显,空间不够了,需要大家挤一挤,怎么个挤发,就需要按照flex-shrink的约定来让出自己的部分空间。例如,三个div原来都需要占用104px的空间,总共要占用312px的空间,现在只有300px,缺少12px。按照flex-shrink的约定,三个div按照1:1:2来分配缺少的12px,三个div分别让出3px(12/(1+1+2))、3px6px的空间,则最终三个div的实际长度分别为101px101px98px,这与浏览器中div的实际长度相等。


同样的,如果有一个div是固定宽度的话,三个div的宽度如何计算呢?看如下的例子:

  1. <div class="as-flex">
  2. <div class="item-1 pink">
  3. <span>1 2 3 4 5 6 7 8 9</span>
  4. </div>
  5. <div class="item-2 lightblue">
  6. <span>1 2 3 4 5 6 7 8 9</span>
  7. </div>
  8. <div class="width208 lightgray">
  9. <span>1 2 3 4 5 6 7 8 9</span>
  10. </div>
  11. </div>
  12. <style type="text/css">
  13. *{
  14. margin: 0;
  15. padding: 0;
  16. }
  17. .as-flex{
  18. display: flex;
  19. }
  20. .item-1{
  21. flex-shrink: 1;
  22. }
  23. .item-2{
  24. flex-shrink: 2;
  25. }
  26. .width208{
  27. width: 208px;
  28. }
  29. .pink{
  30. background: pink;
  31. }
  32. .lightblue{
  33. background: lightblue;
  34. }
  35. .lightgray{
  36. background: lightgray
  37. }
  38. </style>
  1. <div class="outer">
  2. <div class="div1"></div>
  3. <div class="div2"></div>
  4. <div class="div3"></div>
  5. </div>
  6. .outer { width: 500px; display: flex; }
  7. .outer div { height: 80px; }
  8. .div1 { flex: 1 1 100px; background: red; }
  9. .div2 { flex: 1 2 200px; background: yellow; }
  10. .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-200
1/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