为什么flexbox项目图像的大小会根据其初始大小而有所不同



我有四个图像:两个小图像,两个大图像(尺寸显示在html中)。它们的img宽度都设置为100%,但它们的父div设置为特定的宽度。当我调整浏览器窗口的大小时,较小的图像会立即缩小,而较大的图像则不会缩小。

我在潜水艇周围有一个红色的边界,在潜水艇附近有一个绿色的边界。较小图像的绿色边框在较大图像之前缩小。为什么?

http://jsfiddle.net/brcrnj80/6/

img {
  border: 3px solid green;
  width: 100%;
}
.item {
  border: 1px solid red;
  max-width: 250px;
  min-width: 60px;
  margin: 10px;
}

感谢

tl;dr:这些项目的大小不同,因为它们有不同的flex-basis,这是基于图像大小的,也是它们开始弯曲(收缩)的值。每个项目都必须缩小,但较大的项目从较大的起点开始缩小,因此缩小后它们仍然较大。(算法中还有一个后期的"箝位"来防止它们比max-width大;这就是在这种情况下防止大型物品变得疯狂巨大的原因。但重要的是,它们从flex-basis开始缩小,而max-width箝位是事后才想到的。)

FIX:如果你给每个弹性项目相同的弹性基础,例如flex-basis:250px(与它们的max-width相同),你可能会得到你想要的结果。更新的小提琴:http://jsfiddle.net/brcrnj80/10/

(正如另一个答案中所指出的,flex: 1 1 0(可以更简洁地表示为flex:1)也会起作用——即将flex-basis设置为0,并允许弹性项从那里增长(而不是强迫它们收缩),直到它们的最大宽度。只需通过不同的路线即可产生相同的结果。)

更长的解释:以下是发生的情况:

  1. 默认情况下,所有东西都有flex-basis:auto,在这种情况下,这意味着每个柔性项都以其图像的固有宽度开始弯曲。因此,你的大型图像弹性项目有一个巨大的弹性基础,而你的小型图像弹性项目则有一个较小的弹性基础
  2. 我们查看flex项的flex-basis值之和是否大于容器。它们是(因为你的一些图片是巨大的)。所以,我们必须缩小规模
  3. 我们从flex-basis开始"公平"地收缩每个弹性项目,以使所有项目都适合。例如,每个项目都会损失其宽度的1/4(如果这恰好是使它们完全适合容器的正确分数)
  4. 现在,我们检查这些"暂定"物品尺寸中是否有任何一个违反了物品的max-width。具有大图像的弹性项目在这种状态下很可能会违反其max-width,因为例如,即使我们去掉了它们大小的1/4(在我的示例中),它们仍然比它们的max-width:250px大得多。对于任何此类违规行为,我们将项目冻结在其最大宽度,然后重新启动收缩过程。(我们对min-width违规行为做了类似的处理。)
  5. 在重新启动的收缩过程中,大图像被冻结在250px的宽度,而小图像负责所有的收缩

因此,如果没有足够的空间让每个人都有250像素的宽度,那么你的小弹性物品最终不得不进行所有的收缩。(除非我们受到足够的限制,在第一轮收缩中,大项目会收缩到小于250px——例如,如果我们将每个项目收缩90%。不过,那么小项目也会收缩90%,它们会小于min-width:60px,它们会被冻结在这个大小,我们将以与我上述相同的方式重新开始收缩)。

如果你很好奇,请参阅规范中的"解决灵活长度"部分,了解更多详细信息。

这是chrome和Firefox之间的渲染差异,但很容易通过以下方式解决:

.item { flex: 1 1 0; }

这告诉浏览器,所有flex项都应该以0宽度开始,并且所有项都以相同的速度增长以填充剩余的空间。

当我查看您的JSFiddle时,问题很简单,图像框大小不包括边框,因为它需要这样明确说明:

img { box-sizing: border-box; }

img标记不受flexbox的影响,flexbox只影响它们在JSFiddle中的父div(http://jsfiddle.net/brcrnj80/6/)我认为市场上的每个CSS框架都默认将其作为全局定义,这让我们忘记了在需要时需要自己设置它。

最新更新