聊聊Flexbox布局中的flex的演算法

35次阅读

共计 11611 个字符,预计需要花费 30 分钟才能阅读完成。

到目前为止,Flexbox 布局应该是目前最流行的布局方式之一了。而 Flexbox 布局的最大特性就是让 Flex 项目可伸缩,也就是让 Flex 项目的宽度和高度可以自动填充 Flex 容器剩余的空间或者缩小 Flex 项目适配 Flex 容器不足的宽度。而这一切都是依赖于 Flexbox 属性中的 flex 属性来完成。一个 Flex 容器会等比的按照各 Flex 项目的扩展比率分配 Flex 容器剩余空间,也会按照收缩比率来缩小各 Flex 项目,以免 Flex 项目溢出 Flex 容器。但其中 Flex 项目又是如何计算呢?他和扩展比率或收缩比率之间又存在什么关系呢?在这篇文章中我们将一起来探来。
在 Flexbox 布局中,容器中显示式使用 display 设置为 flex 或 inline-flex,那么该容器就是 Flex 容器,而该容器的所有子元素就是 Flex 项目。
简介
在这篇文章中,我们将要聊的是有关于 flex 属性的事情,特别是如何使用该属性来计算 Flex 项目?在开始之前,先来简单的了解一下 flex 属性。
在 Flexbox 中,flex 属性是 flex-grow(扩展比率)、flex-shrink(收缩比率)和 flex-basis(伸缩基准)三个属性的简称。这三个属性可以控制一个 Flex 项目(也有人称为 Flex 元素),主要表现在以下几个方面:

flex-grow:Flex 项目的扩展比率,让 Flex 项目得到(伸张)多少 Flex 容器多余的空间(Positive free space)

flex-shrink:Flex 项目收缩比率,让 Flex 项目减去 Flex 容器不足的空间(Negative free space)

flex-basis:Flex 项目未扩展或收缩之前,它的大小是多少

在 Flexbox 布局中,只有充分理解了这三个属性才能彻底的掌握 Flex 项目是如何扩展和收缩的,也才能更彻底的掌握 Flexbox 布局。因此掌握这三个属性,以及他们之间的计算关系才是掌握 Flexbox 布局的关键所在。
相关概念
在具体介绍 flex 相关的技术之前,先对几个概念进行描述,因为理解了这几个概念更有易于大家对后面知识的理解。
主轴长度和主轴长度属性
Flex 项目在主轴方向的宽度或高度就是 Flex 项目的主轴长度,Flex 项目的主轴长度属性是 width 或 height 属性,具体是哪一个属性,将会由主轴方向决定。

剩余空间和不足空间
在 Flexbox 布局中,Flex 容器中包含一个或多个 Flex 项目(该容器的子元素或子节点)。Flex 容器和 Flex 项目都有其自身的尺寸大小,那么就会有:Flex 项目尺寸大小之和大于或小于 Flex 容器 情景:

当所有 Flex 项目尺寸大小之和小于 Flex 容器时,Flex 容器就会有多余的空间没有被填充,那么这个空间就被称为 Flex 容器的剩余空间(Positive Free Space)

当所有 Flex 项目尺寸大小之和大于 Flex 容器时,Flex 容器就没有足够的空间容纳所有 Flex 项目,那么多出来的这个空间就被称为负空间(Negative Free Space)

举个例子向大家阐述这两个情形:“假设我们有一个容器(Flex 容器),显式的给其设置了 width 为 800px,padding 为 10px,并且 box-sizing 设置为 border-box”。根据 CSS 的盒模型原理,我们可以知道 Flex 容器的内宽度(Content 盒子的宽度)为 800px – 10px * 2 = 780px:

假设 Flex 容器中包含了四个 Flex 项目,而且每个 Flex 项目的 width 都为 100px,那么所有 Flex 项目的宽度总和则是 100px * 4 = 400px(Flex 项目没有设置其他任何有关于盒模型的尺寸),那么 Flex 容器将会有剩余的空间出来,即 780px – 400px = 380px。这个 380px 就是我们所说的 Flex 容器的剩余空间:

假设把 Flex 项目的 width 从 100px 调到 300px,那么所有 Flex 项目的宽度总和就变成了 300px * 4 = 1200px。这个时候 Flex 项目就溢出了 Flex 容器,这个溢出的宽度,即 1200px – 780px = 420px。这个 420px 就是我们所说的 Flex 容器的不足空间:

上面演示的是主轴在 x 轴方向,如果主轴变成 y 轴的方向,同样存在上述两种情形,只不过把 width 变成了 height。接下来的内容中,如果没有特殊说明,那么所看到的示例都仅演示主轴在 x 轴的方向,即 flex-direction 为 row!

min-content 和 max-content
min-content 和 max-content 是 CSS 中的一个新概念,隶属于 CSS Intrinsic and Extrinsic Sizing Specification 模块。简单的可以这么理解。
CSS 可以给任何一个元素显式的通过 width 属性指定元素内容区域的宽度,内容区域在元素 padding、border 和 margin 里面。该属性也是 CSS 盒模型众多属性之一。
记住,CSS 的 box-sizing 可以决定 width 的计算方式。
如果我们显式设置 width 为关键词 auto 时,元素的 width 将会根据元素自身的内容来决定宽度。而其中的 min-content 和 max-content 也会根据元素的内容来决定宽度,只不过和 auto 有较大的差异

min-content:元素固有的最小宽度

max-content:元素固有的首选宽度

比如下面这个示例:

如果内容是英文的话,min-content 的宽度将取决于内容中最长的单词宽度,中文就有点怪异(其中之因目前并未深究),而 max-content 则会计算内容排整行的宽度,有点类似于加上了 white-space:nowrap 一样。
上例仅展示了 min-content 和 max-content 最基本的渲染效果(Chrome 浏览器渲染行为)。这里不做深入的探讨论,毕竟不是本文的重点,如果感兴趣,欢迎关注后续的相关更新,或者先阅读 @张鑫旭 老师写的一篇文章《理解 CSS3 max/min-content 及 fit-content 等 width 值》
回到我们自己的主题上来。
前面在介绍 Flex 剩余空间和不足空间的时候,我们可以得知,出现这两种现象取决于 Flex 容器和 Flex 项目的尺寸大小。而 flex 属性可以根据 Flex 容器的剩余空间(或不足空间)对 Flex 项目进行扩展(或收缩)。那么为了计算出有多少 Flex 容器的剩余空间能用于 Flex 项目上,客户端(浏览器)就必须知道 Flex 项目的尺寸大小。要是没有显式的设置元素的 width 属性,那么问题就来了,浏览器它是如何解决没有应用于绝对单位的宽度(或高度)的 Flex 项目,即如何计算?
这里所说的 min-content 和 max-content 两个属性值对于我们深入的探讨 flex 属性中的 flex-grow 和 flex-grow 属性有一定的影响。所以提前向大家简单的阐述一正是这两个属性值在浏览器中的渲染行为。
简单的总结一下:min-content 的大小,从本质上讲,是由字符串中最长的单词决定了大小;max-content 则和 min-content 想反. 它会变得尽可能大, 没有自动换行的机会。如果 Flex 容器太窄,它就会溢出其自身的盒子!

Flex 项目的计算
在 Flexbox 布局当中,其中 flex-grow、flex-shrink 和 flex-basis 都将会影响 Flex 项目的计算。接下来我们通过一些简单的示例来阐述这方面的知识。
flex-basis
flex-basis 属性在任何空间分配发生之前初始化 Flex 项目的尺寸。其默认值为 auto。如果 flex-basis 的值设置为 auto,浏览器将先检查 Flex 项目的主尺寸是否设置了绝对值再计算出 Flex 项目的初始值。比如说,你给 Flex 项目设置的 width 为 200px,那么 200px 就是 Flex 项目的 flex-basis 值。
如果你的 Flex 项目可以自动调整大小,则 auto 会解析为其内容的大小,这个时候,min-content 和 max-content 变会起作用。此时将会把 Flex 项目的 max-content 作为 flex-basise 的值。比如,下面这样的一个简单示例:
flex-grow 和 flex-shrink 的值都为 0,第一个 Flex 项目的 width 为 150px,相当于 flex-basis 的值为 150px,而另外两个 Flex 项目在没有设置宽度的情况之下,其宽度由内容的宽度来设置。

如果 flex-basis 的值设置为关键词 content,会导致 Flex 项目根据其内容大小来设置 Flex 项目,叧怕是 Flex 项目显式的设置了 width 的值。到目前为止,content 还未得到浏览器很好的支持。
flex-basis 除了可以设置 auto、content、fill、max-content、min-content 和 fit-content 关键词之外,还可以设置 <length> 值。如果 <length> 值是一个百分比值,那么 Flex 项目的大小将会根据 Flex 容器的 width 进行计算。比如下面这个示例:

Flex 容器显式设置了 width(和 box-sizing 取值有关系,上图为 border-box 的示例结果),那么 flex-basis 会根据 Flex 容器的 width 计算出来,如果 Flex 容器未显示设置 width 值,则计算出来的结果将是未定义的(会自动根据 Flex 容器的宽度进行计算)。
在 Flexbox 布局中,如果你想完全忽略 Flex 项目的尺寸,则可以将 flex-basis 设置为 0。这样的设置,基本上是告诉了浏览器,Flex 容器所有空间都可以按照相关的比例进行分配。
来看一个简单的示例,Flex 项目未显式设置 width 情况之下,flex-basis 不同取值的渲染效果。
到写这篇文章为止,使用 Firefox 浏览器查看效果更佳。

当 Flex 项目显式的设置了 min-width 或 max-width 的值时,就算 Flex 项目显式的设置了 flex-basis 的值,也会按 min-width 和 max-width 设置 Flex 项目宽度。当计算的值大于 max-width 时,则按 max-width 设置 Flex 项目宽度;当计算的值小于 min-width 时,则按 min-width 设置 Flex 项目宽度:

有关于 flex-basis 属性相关的运用简单的小结一下:

flex-basis 默认值为 auto

如果 Flex 项目显式的设置了 width 值,同时 flex-basis 为 auto 时,则 Flex 项目的宽度为按 width 来计算,如果未显式设置 width,则按 Flex 项目的内容宽度来计算
如果 Flex 项目显式的设置了 width 值,同时显式设置了 flex-basis 的具体值,则 Flex 项目会忽略 width 值,会按 flex-basis 来计算 Flex 项目
当 Flex 容器剩余空间不足时,Flex 项目的实际宽度并不会按 flex-basis 来计算,会根据 flex-grow 和 flex-shrink 设置的值给 Flex 项目分配相应的空间
对于 Flexbox 布局中,不建议显式的设置 Flex 项目的 width 值,而是通过 flex-basis 来控制 Flex 项目的宽度,这样更具弹性
如果 Flex 项目显式的设置了 min-width 或 max-width 值时,当 flex-basis 计算出来的值小于 min-width 则按 min-width 值设置 Flex 项目宽度,反之,计算出来的值大于 max-width 值时,则按 max-width 的值设置 Flex 项目宽度

flex-grow
前面提到过,flex-grow 是一个扩展因子(扩展比例)。其意思是,当 Flex 容器有一定的剩余空间时,flex-grow 可以让 Flex 项目分配 Flex 容器剩余的空间,每个 Flex 项目将根据 flex-grow 因子扩展,从而让 Flex 项目布满整个 Flex 容器(有效利用 Flex 容器的剩余空间)。
flex-grow 的默认值是 0,其接受的值是一个数值,也可以是一个小数值,但不支持负值。一旦 flex-grow 的值是一个大于 0 的值时,Flex 项目就会占用 Flex 容器的剩余空间。在使用 flex-grow 时可以按下面的方式使用:

所有 Flex 项目设置相同的 flex-grow 值
每个 Flex 项目设置不同的 flex-grow 值

不同的设置得到的效果将会不一样,但 flex-grow 的值始终总量为 1,即 Flex 项目占有的量之和(分子)和分母相同。我们来具体看看 flex-grow 对 Flex 项目的影响。
当所有的 Flex 项目具有一个相同的 flex-grow 值时,那么 Flex 项目将会平均分配 Flex 容器剩余的空间。在这种情况之下将 flex-grow 的值设置为 1。比如下面这个示例,Flex 容器(width: 800px,padding: 10px)中有四个子元素(Flex 项目),显式的设置了 flex-basis 为 150px,根据前面介绍的内容,我们可以知道每个 Flex 项目的宽度是 150px,这样一来,所有 Flex 项目宽度总和为 150px * 4 = 600px。容器的剩余空间为 780px – 600px = 180px。当显式的给所有 Flex 项目设置了 flex-grow 为 1(具有相同的值)。这样一来,其告诉浏览器,把 Flex 容器剩余的宽度(180px)平均分成了四份,即:180px / 4 = 45px。而 flex-grow 的特性就是按比例把 Flex 容器剩余空间分配给 Flex 项目(当然要设置了该值的 Flex 项目),就该例而言,就是给每个 Flex 项目添加了 45px,也就是说,此时 Flex 项目的宽度从 150px 扩展到了 195px(150px + 45px = 195px)。如下图所示:

特别声明,如果 Flex 项目均分 Flex 容器剩余的空间,只要给 Flex 项目设置相同的 flex-grow 值,大于 1 即可。比如把 flex-grow 设置为 10,就上例而言,把剩余空间分成了 40 份,每个 Flex 项目占 10 份。其最终的效果和设置为 1 是等效的。
上面我们看到的均分 Flex 容器剩余空间,事实上我们也可以给不同的 Flex 项目设置不同的 flex-grow 值,这样一来就会让每个 Flex 项目根据自己所占的比例来占用 Flex 容器剩余的空间。比如上面的示例,把 Flex 项目的 flex-grow 分别设置为 1:2:3:4。也就是说把 Flex 容器的剩余空间分成了 10 份(1 + 2 + 3 + 4 = 10),而每个 Flex 项目分别占用 Flex 容器剩余空间的 1 /10、2/10、3/10 和 4 /10。就上例而言,Flex 容器剩余空间是 180px,按这样的计算可以得知,每一份的长度是 180px / 10 = 18px,如此一来,每个 Flex 项目的宽度则变成:

Flex1: 150px + 18px * 1 = 168px

Flex2: 150px + 18px * 2 = 186px

Flex3: 150px + 18px * 3 = 204px

Flex4: 150px + 18px * 4 = 222px

最终效果如下图所示:

前面两个示例向大家演示了,Flex 项目均分和非均分 Flex 容器剩余的空间。从示例中可以看出来,flex-grow 的值都是大于或等于 1 的数值。事实上,flex-grow 还可以设置小数。比如,给所有 Flex 项目设置 flex-grow 的值为 0.2。由于 Flex 项目的 flex-grow 的值都相等,所以扩展的值也是一样的,唯一不同的是,所有的 Flex 项目并没有把 Flex 容器剩余空间全部分完。就我们这个示例而言,四个 Flex 项目的 flex-grow 加起来的值是 0.8,小于 1。换句话说,四个 Flex 项目只分配了 Flex 容器剩余空度的 80%,按上例的数据来计算,即是 180px * .8 = 144px(只分去了 144px),而且每个 Flex 项目分得都是 36px(144px / 4 = 36px 或者 144px * 0.2 / 0.8 = 36px)。最终效果如下图所示:

上面的示例中,flex-basis 都显式的设置了值。事实上,flex-grow 和 flex-basis 会相互影响的。这也令我们的 Flex 项目计算变得复杂化了。比如说,flex-basis 的值为 auto,而且没有给 Flex 项目显式的设置 width。根据前面的内容我们可以得知,此时 Flex 项目的大小都取决于其内容的 max-content 大小。此时 Flex 容器的剩余的空间将由浏览器根据 Flex 项目的内容宽度来计算。比如接下来的这个示例,四个 Flex 项目都是由其内容 max-content 大小决定。同时将 flex-grow 都设置为 1(均匀分配 Flex 容器剩余空间)。具体的数据由下图所示(Chrome 浏览器计算得出的值):

特别注意,不同浏览器对小数位的计算略有差异,上图是在 Chrome 浏览器下得出的值。所以最终加起来的值略大于 Flex 容器的宽度 708px。
针对这样的使用场景,如果你想让所有 Flex 项目具有相同的尺寸,那么可以显式的设置 Flex 项目的 flex-basis 值为 0(flex: 1 1 0)。从 flex-basis 一节中可以得知,当 flex-basis 值为 0 时,表示所有空间都可以用来分配,而且 flex-grow 具有相同的值,因此 Flex 项目可以获取均匀的空间。如此一来 Flex 项目宽度将会相同。

flex-basis 还可以由其他值为设置 Flex 项目的宽度,这里不再一一演示。感兴趣的同学可以自己根据 flex-basis 的取值写测试用例。换句话说,如果你理解了前面介绍的 flex-basis 内容,就能更好的理解 flex-grow 和 flex-basis 相结合对 Flex 项目分配 Flex 容器剩余空间的计算。也将不会再感到困惑。
flex-shrink
flex-shrink 和 flex-grow 类似,只不过 flex-shrink 是用来控制 Flex 项目缩放因子。当所有 Flex 项目宽度之和大于 Flex 容器时,将会溢出容器(flex-wrap 为 nowrap 时),flex-shrink 就可以根据 Flex 项目设置的数值比例来分配 Flex 容器的不足空间,也就是按比例因子缩小自身的宽度,以免溢出 Flex 容器。
flex-shrink 接收一个 <number> 值,其默认值为 1。也就是说,只要容器宽度不足够容纳所有 Flex 项目时,所有 Flex 项目默认都会收缩。如果你不想让 Flex 项目进行收缩时,可以设置其值为 0,此时 Flex 项目始终会保持原始的 fit-content 宽度。同样的,flex-shrink 也不接受一个负值做为属性值。
基于上面的示例,简单的调整一下参数,所有 Flex 项目都设置了 flex: 0 0 300px,可以看到 Flex 项目溢出了 Flex 容器:

在这个示例中,由于 flex-shrink 显式的设置了值为 0,Flex 项目不会进行收缩。如果你想让 Flex 项目进行收缩,那么可以把 flex-shrink 设置为 1。

从上图的结果我们可以看出,当所有 Flex 项目的 flex-shrink 都设置为相同的值,比如 1,将会均分 Flex 容器不足空间。比如此例,所有 Flex 项目的宽度总和是 1200px(flex-basis: 300px),而 Flex 容器宽度是 780px(width: 800px,padding: 10px,盒模型是 border-box),可以算出 Flex 容器不足空间为 420px(1200 – 780 = 420px),因为所有 Flex 项目的 flex-shrink 为 1,其告诉浏览器,将 Flex 容器不足空间均分成四份,那么每份则是 105px(420 / 4 = 105px),这个时候 Flex 项目就会自动缩放 105px,其宽度就由当初的 300px 变成了 195px(300 – 105 = 195px)。
这个示例演示的是 Flex 项目设置的值都是相同的值,其最终结果是将会均分 Flex 容器不足空间。其实 flex-shrink 也可以像 flex-grow 一样,为不同的 Flex 项目设置不同的比例因子。比如 1:2:3:4,这个时候 Flex 项目就不会均分了,而是按自己的比例进行收缩,比例因子越大,收缩的将越多。如下图所示:

就上图而言,所有 Flex 项目的 flex-shrink 之和为 10(1 + 2 + 3 + 4 = 10),此时把 Flex 容器不足空间 420px 分成了十份,每一份 42px(420 / 10 = 42px),每个 Flex 项目按照自己的收缩因子相应的去收缩对应的宽度,此时每个 Flex 项目的宽度就变成:

Flex1: 300 – 42 * 1 = 258px

Flex2: 300 – 42 * 2 = 216px

Flex3: 300 – 42 * 3 = 174px

Flex4: 300 – 42 * 4 = 132px

按照该原理来计算的话,当某个 Flex 项目的收缩因子设置较大时,就有可能会出现小于 0 的现象。基于上例,如果把第四个 Flex 项目的 flex-shrink 设置为 15。这样一来,四个 Flex 项目的收缩因子就变成:1:2:3:15。也就是说把 Flex 容器不足空间分成了 21 份,每份占据的宽度是 20px(420 / 21 = 20px)。那么 Flex 项目的宽度就会出现 0 的现象(300 – 15 * 20 = 0)。这个时候会不会出现无空间容纳 Flex 项目的内容呢?事实上并不会这样:
在 Flexbox 布局当中,会阻止 Flex 项目元素宽度缩小至 0。此时 Flex 项目会以 min-content 的大小进行计算,这个大小是它们利用任何可以利用的自动断行机会后所变成的
如果某个 Flex 项目按照收缩因子计算得出宽度趋近于 0 时,Flex 项目将会按照该元素的 min-content 的大小来设置宽度,同时这个宽度将会转嫁到其他的 Flex 项目,再按相应的收缩因子进行收缩。比如上例,Flex 项目四,其 flex-shrink 为 15,但其宽度最终是以 min-content 来计算(在该例中,Chrome 浏览器渲染的宽度大约是 22.09px)。而这个 22.09px 最终按照 1:2:3 的比例分配给了 Flex 项目一至三(Flex1,Flex2 和 Flex3)。对应的 Flex 项目宽度就变成:

Flex1: 300 – 20 * 1 – 22.09 / 6 * 1 = 276.334px

Flex2: 300 – 20 * 2 – 22.09 / 6 * 2 = 252.636px

Flex3: 300 – 20 * 3 – 22.09 / 6 * 3 = 228.955px

Flex4: min-content,在该例中大约是 22.09px

对于该情形,计算相对而言就更为复杂一些了。但浏览器会很聪明的帮你处理这些场景,会倾向于给你合理的结果。只不过大家需要知道这样的一个细节,碰到类似的场景才不会一脸蒙逼(^_^)。
flex-grow 可以设置一个小于 0 的值,同样的,flex-shrink 也可以设置一个小于 0 的值,比如我们给所有的 Flex 项目设置 flex-shrink 的值为 0.2,你将看到的结果如下:

从结果的示例图中我们可以看出来,当所有 Flex 项目的收缩因子(flex-shrink)总和小于 1 时,Flex 容器不足空间不会完全分配完,依旧会溢出 Flex 容器。好比该例,flex-shrink 的总和是.8,分配了 Flex 容器剩余空间 420px 的 80%,即 336px(还有 84px 剩余空间未完全分配完),由于每个 Flex 项目的收缩因子是相同的,好比前面的示例,都设置了 1 类似,把分配的空间 336px 均分为四份,也就是 84px,因此每个 Flex 项目的宽度由当初的 300px 变成了 216px(300 – 84 = 216px)。这个其实和 flex-grow 类似,只不过 flex-shrink 只是收缩而以。
Flex 项目计算公式
Flex 项目伸缩计算是一个较为复杂的过程,但它们之间还是有据可查。@Chris 和 @Otree 对该方面就有深入的研究。他们给 Flex 项目的计算总结出了一套计算公式,具体公式如下:

@Chris 还依据这套公式写了一个 JavaScript 的案例,来模拟 Flex 项目计算。
flex 常见的值
大部分情形之下,我们都是使用 flex 属性来设置 Flex 项目的伸缩的值。其常见值的效果有:

flex: 0 auto 和 flex:initial,这两个值与 flex: 0 1 auto 相同,也是初始值。会根据 width 属性决定 Flex 项目的尺寸。当 Flex 容器有剩余空间时,Flex 项目无法扩展;当 Flex 容器有不足空间时,Flex 项目收缩到其最小值 min-content。

flex: auto 与 flex: 1 1 auto 相同。Flex 项目会根据 width 来决定大小,但是完全可以扩展 Flex 容器剩余的空间。如果所有 Flex 项目均为 flex: auto、flex:initial 或 flex: none,则 Flex 项目尺寸决定后,Flex 容器剩余空间会被平均分给是 flex:a uto 的 Flex 项目。

flex: none 与 flex: 0 0 auto 相同。Flex 项目根据 width 决定大小,但是完全不可伸缩,其效果和 initial 类似,这种情况下,即使在 Flex 容器空间不够而溢出的情况之下,Flex 项目也不会收缩。

flex: <positive-number>(正数)与 flex: 1 0px 相同。该值使 Flex 项目可伸缩,并将 flex-basis 值设置为 0,导致 Flex 项目会根据设置的比例因子来计算 Flex 容器的剩余空间。如果所有 Flex 项目都使用该模式,则它们的尺寸会正比于指定的伸缩比。

默认状态下,伸缩项目不会收缩至比其最小内容尺寸(最长的英文词或是固定尺寸元素的长度)更小。可以靠设置 min-width 属性来改变这个默认状态。
如何掌握 Flex 项目的大小
通过前面的内容介绍,应该可以了解到 Flex 项目的大小计算是非常的复杂。如果要真正的理解 Flex 项目是如何工作的话,最为关键的是理解有多少东西参与影响 Flex 项目。我们可以按下面这样的方式来进行思考。
怎么设置 Flex 项目的基本大小
在 CSS 中设置一个元素的基本大小可以通过 width 来设置,或者通过 min-width 或 max-width 来设置元素的最小或最大宽度,在未来我们还可以通过 content、min-content、max-content 或 fit-content 等关键词来设置元素的大小。对于 Flex 项目,我们还可以通过 flex-basis 设置 Flex 项目大小。对于如何设置 Flex 项目的基本大小,我们可以围绕以下几点来进行思考:

flex-basis 的值是 auto?Flex 项目显式的设置了宽度吗?如果设置了,Flex 项目的大小将会基于设置的宽度

flex-basis 的值是 auto 还是 content?如果是 auto,Flex 项目的大小为原始大小

flex-basis 的值是 0 的长度单位吗?如果是这样那这就是 Flex 项目的大小

flex-basis 的值是 0 呢? 如果是这样,则 Flex 项目的大小不在 Flex 容器空间分配计算的考虑之内

更为具体的可以参阅 flex-basis 相关的介绍。
我们有可用空间吗?
如果 Flex 容器没有剩余空间,Flex 项目就不会扩展;如果 Flex 容器没有不足空间,Flex 项目就不会收缩:

所有的 Flex 项目的宽度总和是否小于 Flex 容器的总宽度?如果是这样,那么 Flex 容器有剩余空间,flex-grow 会发挥作用,具体如何发挥作用,可以参阅 flex-grow 相关的介绍
所有的 Flex 项目的宽度总和是否大于 Flex 容器的总宽度?如果是这样,那么 Flex 容器有不足空间,flex-shrink 会发挥作用,具体如何发挥作用,可以参阅 flex-shrink 相关的介绍

分配空间的其他方式
如果我们不想把 Flex 容器的剩余空间扩展到 Flex 项目中,我们可以使用 Flexbox 中其他属性,比如 justify-content 属性来分配剩余空间。当然也可以给 Flex 项目设置 margin 值为处理 Flex 容器剩余空间。不过这一部分没有在这里阐述,如果感兴趣的话,不仿阅读一下 Flexbox 相关的介绍。
总结

很久以为,一直以为 Flexbox 布局中,Flex 项目都会根据 Flex 容器自动计算。而事实上呢?正如文章中介绍的一样,Flex 项目的计算是相当的复杂。设置 Flex 项目大小的值以及 flex-basis、flex-grow 和 flex-shrink 的设置都会对其有较大的影响,而且它们的组合场景也是非常的多,并且不同的场景会造成不一样的结果。
当然,文章中所介绍的内容或许没有覆盖到所有的场景,但这些基本的演示或许能帮助大家更好的理解 Flex 项目是如何计算的。最后希望该文对大家有所帮助,如果你有更深的了解欢迎在下面的评论中与我一起分享。如果文章中有不对之处,还望各路大婶拍正。

本文作者:大漠_w3cplus 阅读原文
本文为云栖社区原创内容,未经允许不得转载。

正文完
 0