使容器在包装时收缩以适合子元素

Make container shrink-to-fit child elements as they wrap

提问人:Mikhail Kornienko 提问时间:5/24/2016 最后编辑:Mo.Mikhail Kornienko 更新时间:11/11/2022 访问量:37828

问:

我试图弄清楚 flexbox 是如何工作的(应该工作?...),适用于以下情况:

.holder {
  width: 500px;
  background: lightgray;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  flex-wrap: nowrap;
}
.v2 {
  width: 320px;
}
.child {
  display: inline-block;
  border: 1px solid black;
  padding: 30px 0px;
  text-align: center;
}
<div class="holder">
  <div class="child">At a glance</div>
  <div class="child">After coverage ends</div>
  <div class="child">Forms &amp; documents</div>
</div>
<br>
<br>
<div class="holder v2">
  <div class="child">At a glance</div>
  <div class="child">After coverage ends</div>
  <div class="child">Forms &amp; documents</div>
</div>
<br>
<br>
<div class="holder v2">
  <div class="child">At a
    <br>glance</div>
  <div class="child">After coverage
    <br>ends</div>
  <div class="child">Forms &amp;
    <br>documents</div>
</div>

JSFiddle 在这里

问题是,当有足够的空间来容纳元素时,我会得到一个漂亮的紧身儿童,两者之间的间距均匀。(第一个,顶部 div 块)

然而,当没有足够的空间并且 children 内部的文本开始换行时,这一切都朝着一个奇怪的方向发展——孩子们不再紧密贴合,即使换行后,flex children 周围也有足够的空间,因为不再适合了,space-around 真的没有机会工作(第二个 div 块)

但是,如果我在发生自动换行符的地方添加手动换行符,那么一切都会按照“应该”的方式布局......(底部,第三块)

我想要的是始终让孩子们紧紧地放在他们的盒子里(黑色边框),无论剩下什么空间,都会在他们之间均匀分布,而我不必添加手动换行符(这在我的情况下不是一个选项)

有可能吗?...

HTML CSS 弹性框

评论


答:

2赞 Wart Claes 5/24/2016 #1

你的块之所以像这样,是因为 CSS 渲染。

在第一种情况下,你摆弄浏览器不知道块何时变得太小而无法容纳它的内容。因此,它一直拉伸,直到达到最大值,然后呈现文本。

在最后一种情况下,你告诉浏览器在哪里中断,这样它就知道元素不应该变宽。

轻松解决此问题的唯一方法是自己设置休息时间。

评论

1赞 Mikhail Kornienko 5/24/2016
谢谢!我担心这样的事情可能会发生......仍然希望存在一些聪明的黑客,因为这看起来是一种相当普遍的情况......
2赞 Wart Claes 5/24/2016
我们在工作中也遇到了类似的问题,我们希望在文本旁边浮动一个图标:codepen.io/WartClaes/pen/grVQrz?editors=1100。只是我们还遇到了一个问题,即块总是呈现全宽,但有很多空白。
74赞 Michael Benjamin 5/24/2016 #2

在 CSS 中,父容器不知道其子容器何时换行。因此,它继续扩大其规模,而忽略了内部发生的事情。

换句话说,浏览器在初始级联上呈现容器。当子项换行时,它不会重排文档。

这就是为什么容器不会收缩包装较窄的布局的原因。它只是继续前进,就好像没有任何东西包裹一样,正如右边的预留空间所证明的那样。

水平空白的最大长度是容器预期存在的元素的长度。

在下面的演示中,可以看到在窗口水平调整大小时出现和消失的空白:DEMO

你需要一个 JavaScript 解决方案(见 这里 和 这里)......或 CSS 媒体查询(请参阅此处)。

在处理换行文本时,在某些情况下,在容器上可能会有所帮助。text-align: right

评论

2赞 Cully 9/10/2022
为什么说“父容器不知道它的子容器何时包装”?为什么它不知道?如果这是规范,那将是有道理的。但并不是说“它不知道”。浏览器开发人员可以获取子项的内容宽度,并相应地调整其容器宽度。
3赞 Ilya Loskutov 11/15/2022
容器在宽度方面不知道其内容物的包装,但在高度方面却知道它,这是怎么回事?(容器会相应地改变其高度以适应其包装内容)
0赞 Michael Benjamin 11/17/2022
@IlyaLoskutov,你能发布一个例子吗?也许是 jsFiddle 中的代码示例。
1赞 Ilya Loskutov 11/18/2022
@MichaelBenjamin这是我关于手头问题的封闭式问题。 充当文本的容器。当文本换行时,容器会改变其高度以适合它(差异可以在我附加的两张图片中观察到),但实际上,它不想将其宽度缩小到换行文本的最长行。在这个例子中,flex box 也是如此(随着物品的包装而改变其高度).item.internal-container
0赞 Michael Benjamin 11/18/2022
这是一个很好的观察。考虑发布一个完整的问题。如果你愿意,可以联系我。
5赞 Rene van der Lende 11/17/2016 #3

好好看看我改变的小提琴

  • .holder 设置为(在类中)widthmax-width.v
  • .holder 修改为及其子项wrapspace-around
  • 为清楚起见,又添加了 2 个 .v
  • 删除了<br>'s
  • 最重要的是,添加到 .childflex: 0 0

Flexbox 几乎总是需要设置,这比 . 根据您需要任的行为方式,修改 和 in 以满足您的需求。(结果看起来也不错)max-widthwidth.childflex-growflex-shrinkflex: 0 0flex: 1 0

...无需 Javascript...

Codrops Flexbox 参考对于理解灵活框布局非常有用。

评论

5赞 Bashu Naimi-Roy 11/4/2021
对于任何想知道的人,都没有达到 OP 的要求;它迫使 Flex 儿童即使有足够的空间来换行他们的文本。比较两个小提琴中的顶部 flex 父级,其中有足够的水平空间,但每个元素的文本仍然换行。flex: 0 0;
0赞 Mark Chapel 9/26/2018 #4

如果你正在寻找一个纯CSS的解决方案,你可以使用类似的东西来设置子项的最小宽度,以便它增长。width: 100px;flex: auto;

示例:https://jsfiddle.net/ncvp7gzs/1

(请注意,这仅在 Chrome 上进行了测试)