浅析 flex-grow、flex-shrink、flex-basis

Flexbox 支持对元素大小的灵活控制。本文重点说说 flex-basisflex-shrinkflex-grow 的算法。css

flex-basis

指定了 flex 元素在主轴方向上的初始大小。默认值是 auto,关于 auto 这个属性值 MDN 上还有一段简史,能够了解下。直接上:chestnut:html

<div class="container">
  <div class="item one">200px</div>
  <div class="item two">500px</div>
</div>
复制代码
.container {
  display: flex;
  width: 1000px;
  height: 50px;
  background-color: green;
}
.item {
  flex-basis: auto;
  height: 100%;
  text-align: center;
  line-height: 50px;
}
.one {
  width: 200px;
  background-color: red;
}
.two {
  width: 500px;
  background-color: orange;
}
复制代码
WX20190424-201645@2x

关键字 auto 的意思好像是把 widthheight 设置为自动,实际上并非这么一回事。auto 的意思是这个项目能够从对应的属性(widthheight)那里得到主尺寸,若是没有设置主尺寸,根据内容肯定大小——相似于行内块或者浮动元素!git

flex-basis 还能设置成 content 值,意思是根据项目内容肯定大小——跟 auto 的区别在于忽略 widthheight 设置的主尺寸。浏览器对 content 关键字支持度不一致!!github

flex: 0 会是什么效果呢?算法

WX20190424-202456@2x

能够看到,子元素的 width 都失效了。其实它是子元素的最小宽度(隐形最小宽度——即使你经过属性指定可伸缩项要收缩,但它们可能也不会收缩到可容纳内容的大小之下。)。将 500px 替换成一个 DOM:浏览器

<div class="item two">
  <div class="two-child">400px</div>
</div>
复制代码
.two-child {
  width: 400px;
}
复制代码

结果以下图所示:flex

WX20190424-204007@2x

flex-grow

属性表示剩余空间的一个比值,默认值是0。回到最初 200px500px 的例子,200 + 500 = 700 并无彻底撑满整个父元素 .container 的宽度,剩余的宽度是如何处理的呢?spa

.one {
  flex-grow: 1;
}
.two {
  flex-grow: 1;
}
复制代码

经过上述样式,就能够将剩余的 300px 平均分给.one .two元素。3d

WX20190424-205440@2x

若是结合下面样式会是怎样的呢?code

.item {
  flex-basis: 0%;
}
复制代码

答案是 .one .two 平分1000px,即各 500px。不受子元素的影响。

WX20190424-210237@2x

flex-shrink

父元素宽度不够时就要压缩子元素的宽度,经过 flex-shrink 配置。缩小不比扩大那么简单,缩小的计算方法会复杂一些。复杂的根源在于,再大的子元素也不能致使小元素压缩得不见了。仍是用最前面的例子:

.one {
  width: 600px;
  flex-shrink: 1;
}
.two {
  width: 800px;
  flex-shrink: 1;
}
复制代码

按照自动放大的方式,应该是 (600+800-1000)/2, .one 应该是 400px.two 应该是600px

WX20190424-211401@2x

结果 .one428.58px,这是如何计算过来的呢?

.one = (600 * 1/(600*1 + 800*1))*1000428.58
.two = (800 * 1/(600*1 + 800*1))*1000571.42
复制代码

咱们换一个比例来验证一下想法:

.one {
  width: 600px;
  flex-shrink: 2;
}
.two {
  width: 800px;
  flex-shrink: 3;
}
复制代码

经过计算咱们获得:

.one = (600*2/(600*2 + 800*3))*400133.33
.two = (800*3/(600*2 + 800*3))*400266.67
复制代码

因此 .one 的宽度是 600 - 133.33 px, .two 的宽度是 800 - 266.67 px。下面验证一下结果:

屏幕快照 2019-04-25 22 24 18 屏幕快照 2019-04-25 22 25 27

Bingo!正如咱们的猜测那样。这里用 A 表示第一个子元素,B 表示第二个子元素。计算公式以下:

A 压缩的大小 = (A.flex-shrink * A.flex-basis) / (A.flex-shrink * A.flex-basis + B.flex-shrink * B.flex-basis) * 整体超出的宽度
B 压缩的大小 = (B.flex-shrink * B.flex-basis) / (A.flex-shrink * A.flex-basis + B.flex-shrink * B.flex-basis) * 整体超出的宽度
复制代码

flex

flexflex-growflex-shrinkflex-basis 的缩写,当 flex-basis 是 0 的时候必定/必须/务必要带上单位,0px 或 0% 任君选择。

留一道思考题,上述最后一个例子,若是给 .one 一个 min-width: 500px; 计算会有什么不一样吗?

欢迎指点缺陷,更多好文前往博客

相关文章
相关标签/搜索