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

Posted

技术标签:

【中文标题】为啥弹性项目不缩小超过内容大小?【英文标题】:Why don't flex items shrink past content size?为什么弹性项目不缩小超过内容大小? 【发布时间】:2020-05-04 16:43:20 【问题描述】:

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

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

观看此video (一开始,第一列是最小的,但是当我调整窗口大小时,它是最宽的列。我只想始终遵守 flex 设置;flex 大小为 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>

【问题讨论】:

【参考方案1】:

对于下面的这段代码,添加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】:

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

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

然后,如果您需要这种行为,只需使用 min-width: automin-height: auto

事实上,还要加上 box-sizing 以使所有布局更加合理:

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

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

【讨论】:

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

弹性项目的自动最小尺寸

您遇到了 flexbox 默认设置。

flex 项不能小于其内容沿主轴的大小。

默认是...

min-width: auto min-height: auto

...分别用于行方向和列方向的弹性项目。

您可以通过将弹性项目设置为:

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

弹性盒规范

4.5. Automatic Minimum Size of Flex Items

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

关于auto 值...

在主轴上overflowvisible 的弹性项目上,当在弹性项目的主轴最小尺寸属性上指定时,指定自动最小尺寸。否则计算为0

换句话说:

min-width: automin-height: auto 默认值仅在 overflowvisible 时适用。 如果overflow的值不是visible,则min-size属性的值是0。 因此,overflow: hidden 可以替代min-width: 0min-height: 0

还有……

最小尺寸算法仅适用于主轴。 例如,默认情况下,行方向容器中的弹性项目不会获得min-height: auto。 有关更详细的说明,请参阅此帖子: min-width rendering differently in flex-direction: row and flex-direction: column

你已经应用了 min-width: 0 并且项目仍然没有缩小?

嵌套 Flex 容器

如果您在 html 结构的多个级别上处理弹性项目,则可能需要覆盖更高级别项目上的默认 min-width: auto / min-height: auto

基本上,带有min-width: auto 的更高级别的弹性项目可以防止嵌套在下面的带有min-width: 0 的项目收缩。

例子:

Flex item is not shrinking smaller than its content Fitting child into parent white-space css property is creating issues with flex

浏览器渲染说明

Chrome 与 Firefox / Edge

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

IE11

如规范中所述,min-widthmin-height 属性的 auto 值是“新的”。这意味着某些浏览器可能仍会默认呈现0 值,因为它们在值更新之前实现了弹性布局,并且因为0min-widthmin-height 在CSS 2.1 中的初始值。 One such browser is IE11. 其他浏览器已更新为 flexbox spec 中定义的较新的 auto 值。


修改后的演示

.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

【讨论】:

我有一个
父标签在 dom 中更高,这导致了同样的问题。将其最小宽度设置为 0 即可修复它。
关于这个的任何想法:***.com/a/36247448/8620333 .. 我发现它与 min-width 有关,但不太确定所有细节。 看起来 Chrome 更改了 v73 中的行为,使其不会缩小到小于内容。 min-height: 0; 相同的修复程序。我不得不尝试为树中的几个更高的元素设置它。 我必须在 ike 10 个地方设置 min-height: 0; 才能让它工作。谢谢,谢谢,谢谢你的精彩提示!

以上是关于为啥弹性项目不缩小超过内容大小?的主要内容,如果未能解决你的问题,请参考以下文章

图像弹性项目不会在弹性框中缩小高度

为啥颤振项目文件大小超过 500MB?

防止弹性项目缩小[重复]

如何防止弹性项目在没有包装的情况下溢出弹性父项?

弹性项目不垂直居中

将弹性项目的跨轴尺寸调整为适合内容