flexbox布局 - pod4g/tool GitHub Wiki

1. 如果子项目都设定了宽度,且宽度相加大于父容器的宽度,则设置flex-grow不起作用

例如:

.container {
  background-color: #eceaec;
  width:500px;
  height:400px;
  display:flex;
}
.item:nth-child(1){
  background-color: #6f5499;
  width: 300px;
  flex-grow: 5; // 不起作用,相当于没有设置
}
.item:nth-child(2){
  background-color: #0275d8;
  width: 100px;
  flex-grow: 1; // 不起作用,相当于没有设置
}
.item:nth-child(3){
  background-color: #ce4844;
  width: 101px;
  flex-grow: 1; // 不起作用,相当于没有设置
}

这个例子的计算规则如下:

容器总宽度:container.width = 500;
item1的宽度:item1.width   = 300;
item2的宽度:item2.width   = 100;
item3的宽度:item3.width   = 101;

则,item的总宽度:item.totalWidth = item1.width + item2.width + item3.width = 501
则 item.totalWidth > container.width
故,flex-grow不再起作用,

则
item1的真实宽度为:300 * 300/501 = 299.401
item2的真实宽度为:100 * 300/501 = 99.800
item3的真实宽度为:101 * 300/501 = 100.788

由上面可知,当item宽度只和大于容器宽度时,各个容器的width属性就相当于比例。

2. item的尺寸可以用flex-basis来设定

flex-basis用来设置item在主轴方向的尺寸,

如果flex-direction:row;,则flex-basis相当于width

如果flex-direction:column;,则flex-basis相当于height

widthheight能用的单位flex-basis一样能用。

假设主轴是水平方向,

如果同时指定flex-basis和width且值都不是auto,则听flex-basis的;

如果两者同时指定,且有值是auto,则听另一个非auto的值,哪怕另外一个值为0;

3. 默认值

flex-grow的默认值是0
flex-shrink的默认值是1
flex-basis的默认值是auto

flex:1;    -> flex: 1 1 0; -> flex-grow:1; flex-shrink:1; flex-basis:0;
flex:auto; -> flex: 1 1 auto;
flex:none; -> flex: 0 0 auto;

由于flex-shrink的默认值为1,所以当items.totalWidth超过container.width时,并不会超出。

4. flex-grow、flex-shrink

当items.totalWidth < container.width 时,item's flex-grow按照其值瓜分剩下的空间;

当items.totalWidth > container.width 是,item's flex-shrink按照其值缩小多出的部分,使父容器正好包含所有的items;

5. 一个例子看flex-basis

遇到一个容易让人迷惑的例子:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.container{
    width: 600px;
    height: 400px;
    background-color: aliceblue;
    color:#fff;
    font-size: 20px;
    display: flex;
}

.one{
    background-color: red;
    flex:1; 
}

.two{
    background-color: green;
    flex-grow: 1;
}
</style>
</head>
<body>
 <div class="container">
     <div class="one"></div>
     <div class="two"></div>
 </div>          
</body>
</html>

上面这个例子中,

.oneflex值为1,相当于flex: 1 1 0;,那么有flex-basis: 0,而 .twoflex相当于flex:1 1 auto;,此时有flex-basis: auto

那么问题来了,flex-basis的值是0和auto,有什么区别呢?

上面的例子中.one最终计算出来的width: 290px.two最终计算出来的width: 310px,原来我认为.one.twoflex-grow值都为1,那么这两者显然应该平分所有剩余空间,计算出来两者都应该为width: 300px,但是结果确显然不是,问题出在哪儿呢?

先看.one,由于flex-basis: 0,则其初始分得的width就是0, 然后.two,他的flex-basisauto,那么.two的初始width,应该正好容纳下它的内容为止, 由于font-size: 20px,那么.two的初始width就是20px(正好容下汉字“贰”),

下面进行计算:

container.width          = 600;
items.totalWidth         = 0 + 20 = 20;
remining space           = container.width - items.totalWidth = 600 - 20 = 580;
flex-grow total value    = 1 + 1 = 2;
one flex-grow size       = 580 / 2 = 290;

one.width = 0  + 1 * 290 = 290;
two.width = 20 + 1 * 290 = 310;

下面我们改一下:

.two{
    background-color: green;
    flex-grow: 1;
    flex-basis: 50px;
}
/*或*/
.two{
    /* 
      由于 flex-basis 没有设置,故其值为默认值,即auto。然后设置了width:50px;
      根据规则可知,两者都存在的话,听值不为auto的。此种情况下,听width的。
    */
    background-color: green;
    flex-grow: 1;
    width: 50px;
}

根据公式进行计算:

container.width          = 600;
items.totalWidth         = 0 + 50 = 50;
remining space           = container.width - items.totalWidth = 600 - 50 = 550;
flex-grow total value    = 1 + 1 = 2;
one flex-grow size       = 550 / 2 = 225;

one.width = 0  + 1 * 225 = 225;
two.width = 50 + 1 * 225 = 275;

如果改变.one的样式:

.one{
    background-color: red;
    flex:1; 
    flex-basis: 112px; 
}

根据公式进行计算:

container.width           = 600;
items.totalWidth          = 112 + 20 = 132;
remining space            = container.width - items.totalWidth = 600 - 132 = 468;
flex-grow total value     = 1 + 1 = 2;
one flex-grow size        = 468 / 2 = 234;

one.width = 112 + 1 * 234 = 346;
two.width = 20  + 1 * 234 = 254;

但是如果改成这样:

.one{
    background-color: red;
    flex:1; 
    width: 112px; 
}

经过计算,.one.two的width分别为290px310px,跟没有width属性的结果一致。原因是:flex-basiswidth都有值,且值都不为auto,所以听flex-basis的,而flex-basis的值为0,所以计算出来的值就跟width不存在一样。

5. flex对image尺寸的影响

下面的例子中,图片原始尺寸为400 x 300,图片所在容器大小为800 x 700, 设置img标签width: 100%,根据img标签尺寸计算可知,指定了一个css属性,则 图片不会被拉伸,会根据比例计算另一个属性。但是在这个例子中,图片却被拉伸了。原因在于 父容器的align-items: stretch;,会在侧轴(即图片的height方向)方向拉伸图片以填满整个容器。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    .container{
      width: 800px;
      height: 700px;
      background-color: aliceblue;
      display: flex;
      /* 如果加上下面的属性则图片在height方向才不会被拉伸 */
      /* align-items: flex-start; */
   }

   .container img{
     width: 100%;
   }
  </style>
</head>
<body>
  <div class="container">
    <img src="http://www.placebacon.net/400/300">
  </div>
</body>
</html>

6. flex对image尺寸的影响

justify-content: space-around; 并不会平分容器剩余的空间

⚠️ **GitHub.com Fallback** ⚠️