深刻理解Flex属性

做者: Yeaseon
Blog:yeaseonzhang.github.io
原文连接css

Flex 是 Flexible Box的缩写,意为“弹性布局”,能够简便、完整、响应式地实现各类页面布局。git

Flex的出现就是为了解决传统布局的display属性 + position属性 + float属性的复杂性。github

浏览器对于Flex的支持性

能够看到浏览器对于Flex布局的支持性已经很好了,因此咱们能够放心大胆的用在咱们项目中。浏览器

flex 属性

flex: flex-grow | flex-shrink | flex-basisbash

flex属性包含三个值:flex-growflex-shrinkflex-basis布局

  • flex-grow: 扩展比例
  • flex-shrink: 收缩比例
  • flex-basis: 伸缩基准值

首先咱们简单写一个flex布局的Demoflex

HTMLspa

<div class="parent">
  <div class="child_1"></div>
  <div class="child_2"></div>
  <div class="child_3"></div>
</div>复制代码

CSScode

.child_1,
.child_2,
.child_3 {
  flex: 1;
  height: 200px;
}

.child_1 {
  background-color: rgba(255, 0, 0, .5);
}

.child_2 {
  background-color: rgba(0, 255, 0, .5);
}

.child_3 {
  background-color: rgba(0, 0, 255, .5);
}复制代码

See the Pen Flex-1 by YeaseonZhang (@YeaseonZhang) on CodePen.cdn

设置父元素display: flex,其子元素就能使用flex布局,咱们只是简单的为子元素使用了flex: 1就实现了三等分,并且会随着父元素的宽度变化而变化。这就是咱们平时flex布局的简单用法,即各个子元素按照比例布局。

flex: 1实际上是flex: 1 1 0%的简写属性,即伸缩比例都是1。下面咱们就分别理解下三个属性值对于布局的影响。

flex-basis 属性

flex-basis属性是伸缩的基准值,这个属性也是咱们计算最终宽度的决定性因素。

经过子元素flex-basis属性和与父元素(容器)宽度值进行比较,会出现两种状况(忽略相等的状况):

  • 子元素flex-basis属性和 < 父元素宽度
  • 子元素flex-basis属性和 > 父元素宽度

上面的两种状况就分别对应了flex-growflex-shrink属性生效的状况,也就是说当子元素的flex-basis属性宽度和小于父元素的宽度值时flex-grow生效,反之flex-shrink生效。

flex-grow 属性

flex-grow属性是扩展比例,上面咱们也谈到了当子元素的flex-basis总和小于父元素的宽度值时flex-grow生效。

如今咱们就来改变CSS,知足这个前提条件。

CSS

.parent {
  display: flex;
  width: 600px;
}

.child_1,
.child_2,
.child_3 {
  height: 200px;
}

.child_1 {
  flex: 1 0 150px;
  background-color: rgba(255, 0, 0, .5);
}

.child_2 {
  flex: 0 0 100px;
  background-color: rgba(0, 255, 0, .5);
}

.child_3 {
  flex: 1 0 150px;
  background-color: rgba(0, 0, 255, .5);
}复制代码

See the Pen Flex-2 by YeaseonZhang (@YeaseonZhang) on CodePen.

此时,各个元素的flex-basis和为(150 + 100 + 150) = 400px, 小于父元素的600px,咱们就来分别计算每一个子元素的宽度值。

可用空间 = 父元素width - 子元素flex-basis总和 => 600 - (150 + 100 + 150) = 200

单位扩展空间 = 可用空间/子元素flex-grow总和 => 200/(1 + 0 + 1) = 100复制代码

子元素的计算公式为width = flex-basis + flex-grow * 单位扩展空间

因此child_1宽度为(150 + 1 * 100) = 250px, child_2宽度为(100 + 0 * 100) = 100px, child_3child_1

flex-shrink 属性

flex-shrink 属性是收缩比例,当子元素的flex-basis总和大于父元素的宽度值时flex-grow生效。

如今咱们就修改CSS知足这个前提。

CSS

.parent {
  display: flex;
  width: 600px;
}

.child_1,
.child_2,
.child_3 {
  /*flex: 1;*/
  height: 200px;
}

.child_1 {
  flex: 0 1 400px;
  background-color: rgba(255, 0, 0, .5);
}

.child_2 {
  flex: 0 1 200px;
  background-color: rgba(0, 255, 0, .5);
}

.child_3 {
  flex: 0 2 400px;
  background-color: rgba(0, 0, 255, .5);
}复制代码

See the Pen Flex-3 by YeaseonZhang (@YeaseonZhang) on CodePen.

固然啦,咱们能够按照flex-grow的计算方法套用。

溢出空间 = 父元素width - 子元素flex-basis总和 => 600 - (400 + 200 + 400) = -400

单位收缩空间 = 溢出空间/子元素flex-shrink总和 => -400/(1 + 2 + 2) = -100复制代码

子元素的计算公式为width = flex-basis + flex-shrink * 单位收缩空间

因此child_1宽度为(400 + 1 * (-100)) = 300px, child_2宽度为(200 + 1 * (-100)) = 100px, child_3(400 + 2 * (-100)) = 200px

大功告成了?其实并无实例状况并非咱们计算的那样300px 100px 200px,而是285.72px 142.86px 171.42px

经过Google,发现了一种收缩因数的计算方法:

理想空间 = 子元素(flex-basis * flex-shrink)之和 => 400 * 1 + 200 * 1 + 400 * 2 = 1400

溢出空间 = 父元素width - 子元素flex-basis总和 => 600 - (400 + 200 + 400) = -400

收缩因数 = (flex-basis * flex-shrink) / 理想空间 => 400 / 1400 = 0.286; 200 / 1400 = 0.143; 800 / 1400 = 0.571复制代码

分别为每一个子元素计算了收缩因数就能计算咱们子元素的实际宽度,子元素的计算公式width = flex-basis + 收缩因数 * 溢出空间

因此child_1宽度为400 + 0.286 * (-400) = 285.6, child_2宽度为200 + 0.143 * (-400) = 142.8, child_3宽度为400 + 0.571 * (-400) = 171.6

如今咱们计算出的值与浏览器渲染出的值基本上是相同的,咱们对于flex属性的了解已经再也不是单单的比例计算了,但愿本文对你有所帮助。

相关文章
相关标签/搜索