为什么弹性项目不缩小超过内容大小?

Why don't flex items shrink past content size?

提问人:tomas657 提问时间:3/27/2016 最后编辑:MrMaavintomas657 更新时间:8/11/2023 访问量:169796

问:

我有 4 个 flexbox 列,一切正常,但是当我向列添加一些文本并将其设置为大字体大小时,由于 flex 属性,它使列比应有的更宽。

我尝试使用并且它有所帮助,但是当我将列的大小调整到非常小的宽度时,文本中的字母会分成多行(每行一个字母),但该列的宽度不会小于一个字母大小。word-break: break-word

观看此视频(开始时,第一列是最小的,但是当我调整窗口大小时,它是最宽的列。我只想始终尊重弹性设置;弹性尺寸 1 : 3 : 4 : 4)

我知道,将字体大小和列填充设置为更小会有所帮助......但是还有其他解决方案吗?

我不能使用.overflow-x: hidden

JSFiddle

.container {
  display: flex;
  width: 100%
}
.col {
  min-height: 200px;
  padding: 30px;
  word-break: break-word
}
.col1 {
  flex: 1;
  background: orange;
  font-size: 80px
}
.col2 {
  flex: 3;
  background: yellow
}
.col3 {
  flex: 4;
  background: skyblue
}
.col4 {
  flex: 4;
  background: red
}
<div class="container">
  <div class="col col1">Lorem ipsum dolor</div>
  <div class="col col2">Lorem ipsum dolor</div>
  <div class="col col3">Lorem ipsum dolor</div>
  <div class="col col4">Lorem ipsum dolor</div>
</div>

HTML CSS 弹性框

评论


答:

1018赞 Michael Benjamin 3/27/2016 #1

Flex 项目的自动最小大小

您遇到了 flexbox 默认设置。

柔性项目不能小于其内容沿主轴的大小。

默认值为...

  • min-width: auto
  • min-height: auto

...分别用于 row-direction 和 column-direction 中的 flex 项目。

您可以通过将 flex 项设置为以下值来覆盖这些默认值:

  • min-width: 0
  • min-height: 0
  • overflow: hidden(或任何其他值,除了visible)

Flexbox 规格

4.5. Flex 的自动最小大小 项目

为了给 flex 项目提供更合理的默认最小大小,这 规范引入了一个新值作为初始值 CSS 2.1 中定义的 和 属性。automin-widthmin-height

关于汽车价值...

在位于主轴的 flex 项上,当在 flex 项的主轴 min-size 属性上指定时,将指定自动最小大小。否则,它将计算为 .overflowvisible0

换言之:

  • 和 缺省值仅在 为 时适用。min-width: automin-height: autooverflowvisible
  • 如果该值不是 ,则 min-size 属性的值为 。overflowvisible0
  • 因此,可以替代 和 。overflow: hiddenmin-width: 0min-height: 0

和。。。


您已经应用了 min-width: 0,但项目仍然没有缩小?

嵌套 Flex 容器

如果要在 HTML 结构的多个级别上处理 flex 项目,则可能需要覆盖更高级别的默认 / on 项目。min-width: automin-height: auto

基本上,更高级别的 flex 项 with 可以防止嵌套在 with 下面的项上收缩。min-width: automin-width: 0

例子:


浏览器渲染说明

  • Chrome 与 Firefox / Edge

    至少从 2017 年开始,Chrome 似乎要么 (1) 恢复到 / 默认值,要么 (2) 在某些情况下基于神秘算法自动应用默认值。(这可能是他们所说的干预。因此,许多人看到他们的布局(尤其是所需的滚动条)在 Chrome 中按预期工作,但在 Firefox / Edge 中却没有。这里更详细地介绍了这个问题:Firefox 和 Chrome 之间的弹性收缩差异min-width: 0min-height: 00

  • IE11的

    如规范中所述,和属性的值为“new”。这意味着某些浏览器可能仍然默认呈现一个值,因为它们在更新值之前实现了 flex 布局,并且因为是 CSS 2.1 和 中的初始值。IE11就是这样一种浏览器。其他浏览器已更新为 flexbox 规范中定义的较新值。automin-widthmin-height00min-widthmin-heightauto


修订后的演示

.container {
  display: flex;
}

.col {
  min-height: 200px;
  padding: 30px;
  word-break: break-word
}

.col1 {
  flex: 1;
  background: orange;
  font-size: 80px;
  min-width: 0;   /* NEW */
}

.col2 {
  flex: 3;
  background: yellow
}

.col3 {
  flex: 4;
  background: skyblue
}

.col4 {
  flex: 4;
  background: red
}
<div class="container">
  <div class="col col1">Lorem ipsum dolor</div>
  <div class="col col2">Lorem ipsum dolor</div>
  <div class="col col3">Lorem ipsum dolor</div>
  <div class="col col4">Lorem ipsum dolor</div>
</div>

jsFiddle

评论

5赞 maccam94 3/26/2019
看起来 Chrome 更改了 v73 中的行为,使其不缩小到小于内容。
4赞 Ben Wheeler 5/25/2019
同样的修复程序也适用于 .我不得不尝试为树中的几个更高元素设置它。min-height: 0;
4赞 dave0688 2/11/2020
我必须设置 10 个地方才能让它工作。谢谢你,谢谢你,谢谢你的好提示!min-height: 0;
1赞 gabriel.santos 10/22/2022
您只是通过描述嵌套弯曲收缩行为解决了我的问题。谢谢
1赞 Michael Benjamin 3/20/2023
@AxelSamyn,这应该作为一个完整的问题发布,并带有重现该场景的代码。
27赞 voracity 8/24/2020 #2

多年来,我发现这在 flex 和 grid 方面都反复困扰着我,所以我将提出以下建议:

* { min-width: 0; min-height: 0; }

然后,如果您需要该行为,则使用 OR。min-width: automin-height: auto

事实上,也要考虑框大小,使所有布局更加合理:

* { box-sizing: border-box; min-width: 0; min-height: 0; }

有谁知道是否有任何奇怪的后果?在混合使用上述方法的几年中,我没有遇到过任何事情。事实上,我想不出任何一种情况,我想从内容向外布局到flex/grid,而不是flex/grid向内布局到内容---当然,如果它们存在,它们很少见。所以这感觉像是一个糟糕的默认值。但也许我错过了什么?

评论

0赞 Jeremy Chone 9/4/2020
是的,副作用是阴影 DOM 和开槽元素,如果要更改此默认的最小宽度,现在需要 !important。
0赞 Jeremy Chone 9/4/2020
顺便说一句,对于 Web 组件的情况,诀窍是使用 css var。这样,您就有了默认值,但可以被覆盖,同时仍然具有上面的 * { mid-width: ..}。:host{ --min-width: 10rem; min-width: var(--min-width) !important; ... } 然后,在 app.css 中,你可以有 c-menu{ --min-width: 30rem; }
3赞 Michael Benjamin 9/7/2020
您建议的默认设置 () 曾经是 flex 的默认值(与 CSS 的其余部分一致)。将规范从 修改为 是有原因的。在切换回它们之前,您可能需要考虑这些原因。如果您对详细信息感兴趣,请从这里开始: w3.org/TR/css-flexbox-1/#min-size-auto00auto
1赞 voracity 9/7/2020
@MichaelBenjamin,奇怪的是,我会说该规范提供了更好的理由来避免基于内容的最低要求。尽管如此,他们提出的主要观点是,它“通常是合适的,并有助于防止内容重叠或溢出到其容器之外”---但这是否比由外而内的布局更需要?我自己的经验表明情况并非如此,“min-<dim>: 0”还没有给我带来任何问题,但我承认@JeremyChone提到的 Web 组件的(实际)问题。如果您有更多关于推理的链接,很乐意查看它们。
14赞 Michael Benjamin 9/7/2020
@voracity - 这篇文章目前有近 64K 的浏览量,接受的答案接近 600 个赞。即使是这个问题的封闭副本(例如这个问题和这个问题)也有数以万计的浏览量和数百个赞成票。所以,是的,这个问题可能需要由规范作者重新审视。
1赞 sunyop 4/23/2021 #3

对于下面的这段代码,添加解决了我的问题。width: 100%

.post-cover .inner {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
    justify-content: center;
    align-content: flex-start;
    align-items: flex-start;
    word-break: break-all;
    z-index: 21;
}
.post-cover .article-page {
    padding: 20px 0;
    margin-bottom: 40px;
    font-size: 0.875em;
    line-height: 2.0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;   /* Add this */
}
2赞 Eve 4/20/2022 #4

对你的问题的纯粹答案是,默认情况下,浏览器倾向于向读者显示尽可能多的信息(而不是隐藏任何内容)。

默认情况下会发生这种情况,甚至包括在白色背景上显示默认的黑色字体(以获得最大的页面对比度和可读性),添加内容大于视口高度(或宽度)的滚动条,或者仍然显示来自标记(或背景颜色)的内容,即使它被错误地放置在 html 文件之后甚至标记之后。</body></html>

在 CSS 的上下文中,这也适用,但您也可以在此基础上进行许多自定义设置。

即使在屏幕中,如果使用大字体(如),这最初也会充当溢出元素(并且使用将字体放置在灵活的子容器中不会更改此默认行为,除非您以某种方式使用或调整元素大小。font-size: 50em;display: flexoverflow: hidden

例如,一个优雅的解决方案是使用字母的动态调整大小

font-size: calc(0.5em + 2vw)

即使在响应式场景中也非常有效。

正如前面的答案所提到的,flex 项目不能小于其内容沿主轴的大小(出于同样的原因,这不仅特定于在 CSS 中实现的 flexbox 模型,还因为内部浏览器的工作方式)。即使是一个长字,如果它长于显示宽度,也会用滚动条显示,就好像它是具有固定大小的块类型元素一样。

这在旧的 html 4.01 规范中被称为

“按照惯例,可视 HTML 用户代理会换行以适应 可用边距。包装算法取决于脚本 格式 化。

例如,在西方文字中,文本只能换行为白色 空间。"

9.5.3 段所示。这意味着,从那时起,文本必须默认连续显示(除非我们决定拆分它,而不是在单个字符级别:以 120em 大小显示的单个非白色字符将触发浏览器上显示的滚动条)。

第9.1段在同一来源中也明确界定了词语:

我们在这里使用术语“词”来表示“非空白空间的序列” 字符”

显示任何单词的原始格式的目的是不破坏、隐藏或歪曲原始信息、代码作者的含义或意图。因此,我们还必须将两个相连的单词保持在同一行中 - 当破坏它们可能会造成破坏时(例如纽约,晚上 10 点,10 公里/小时,§ 10 等)&nbsp;

-3赞 Ike Anya 5/30/2022 #5

我尝试了一切,甚至将以下代码放在索引.css中。

* {
  min-width: 0;
  min-height: 0;
  box-sizing: border-box;
}

但没有任何效果。

最后我做了我想缩小的div,它的内容要有。然后它开始缩小。 它的父 div 需要定义的高度和宽度。这可能不是每种情况的最佳解决方案,但如果这对您有用,那就太好了!position: absolute;

评论

2赞 Gabriel Petersson 12/14/2022
答案与弹性物品的缩小无关,因为现在这些物品不是弹性物品
-1赞 luukvhoudt 8/9/2023 #6

怎么样:

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

.child-with-ellipses {
  flex-basis: auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.child-without-ellipses {
  flex-basis: 69%;
  background-color: red;
}
<div class="parent">
  <div class="child-with-ellipses">
    This node has the class `child-with-ellipses`.
  </div>
  <div class="child-without-ellipses"></div>
</div>

-1赞 Alex Vovchuk 8/11/2023 #7

目前最有效的解决方案是使用: https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp-webkit-line-clamp

您可以指定要保留的行数,例如 1。

基于 的旧解决方案不适用于广泛使用的复杂布局。min-width: 0flex