Flexbox 支持对元素大小的灵活控制。本文重点说说 flex-basis
、flex-shrink
、flex-grow
的算法。css
指定了 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;
}
复制代码
关键字 auto
的意思好像是把 width
或 height
设置为自动,实际上并非这么一回事。auto
的意思是这个项目能够从对应的属性(width
或 height
)那里得到主尺寸,若是没有设置主尺寸,根据内容肯定大小——相似于行内块或者浮动元素!git
flex-basis
还能设置成 content
值,意思是根据项目内容肯定大小——跟 auto
的区别在于忽略 width
和 heigh
t 设置的主尺寸。浏览器对 content
关键字支持度不一致!!github
flex: 0 会是什么效果呢?算法
能够看到,子元素的 width
都失效了。其实它是子元素的最小宽度(隐形最小宽度——即使你经过属性指定可伸缩项要收缩,但它们可能也不会收缩到可容纳内容的大小之下。)。将 500px
替换成一个 DOM:浏览器
<div class="item two">
<div class="two-child">400px</div>
</div>
复制代码
.two-child {
width: 400px;
}
复制代码
结果以下图所示:flex
属性表示剩余空间的一个比值,默认值是0。回到最初 200px
、 500px
的例子,200 + 500 = 700
并无彻底撑满整个父元素 .container
的宽度,剩余的宽度是如何处理的呢?spa
.one {
flex-grow: 1;
}
.two {
flex-grow: 1;
}
复制代码
经过上述样式,就能够将剩余的 300px
平均分给.one .two
元素。3d
若是结合下面样式会是怎样的呢?code
.item {
flex-basis: 0%;
}
复制代码
答案是 .one .two
平分1000px
,即各 500px
。不受子元素的影响。
父元素宽度不够时就要压缩子元素的宽度,经过 flex-shrink 配置。缩小不比扩大那么简单,缩小的计算方法会复杂一些。复杂的根源在于,再大的子元素也不能致使小元素压缩得不见了。仍是用最前面的例子:
.one {
width: 600px;
flex-shrink: 1;
}
.two {
width: 800px;
flex-shrink: 1;
}
复制代码
按照自动放大的方式,应该是 (600+800-1000)/2
, .one
应该是 400px
,.two
应该是600px
:
结果 .one
是 428.58px
,这是如何计算过来的呢?
.one = (600 * 1/(600*1 + 800*1))*1000 ≈ 428.58
.two = (800 * 1/(600*1 + 800*1))*1000 ≈ 571.42
复制代码
咱们换一个比例来验证一下想法:
.one {
width: 600px;
flex-shrink: 2;
}
.two {
width: 800px;
flex-shrink: 3;
}
复制代码
经过计算咱们获得:
.one = (600*2/(600*2 + 800*3))*400 ≈ 133.33
.two = (800*3/(600*2 + 800*3))*400 ≈ 266.67
复制代码
因此 .one
的宽度是 600 - 133.33 px, .two
的宽度是 800 - 266.67 px。下面验证一下结果:
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
是 flex-grow
、flex-shrink
、flex-basis
的缩写,当 flex-basis
是 0 的时候必定/必须/务必要带上单位,0px 或 0% 任君选择。
留一道思考题,上述最后一个例子,若是给 .one 一个 min-width: 500px;
计算会有什么不一样吗?
欢迎指点缺陷,更多好文前往博客!