[2分钟学个CSS小技巧] flex 项中子元素文本溢出截断 text-overflow:ellipsis 失效问题 – flexbox 布局中 flex 项的宽度计算原理

10年服务1亿前端开发工程师

小编推荐:掘金是一个面向程序员的高质量技术社区,从 一线大厂经验分享到前端开发最佳实践,无论是入门还是进阶,来掘金你不会错过前端开发的任何一个技术干货。

本文从 flex 项中子元素文本截断 text-overflow:ellipsis 失效这个小 “bug” 说起,并且给你一个完美的解决方案。但是更重要的是帮助你理解 flexbox 布局中 flex 项的宽度计算原理。

问题

有个小伙伴问我,flexbox 布局时 flex 项子元素中的文本溢出后想显示省略号(…),结果设置 text-overflow:ellipsis 后没效果,我们来看代码:

HTML 代码

<div class="flex">
  <div class="col1">图标</div>
  <div class="col2">
    <div class="item-con">
      flexbox 布局旨在提供一个更有效地布局、对齐方式,并且能够使容器中的子元素大小未知或动态变化情况下仍然能够分配好子元素之间的空间。
    </div>
  </div>
</div>

CSS 代码:

.flex {
  display: flex;
}
.flex .col1 {
  margin-right: 6px;
}
.flex .col2 {
  flex: 1;
}
.flex .col2 .item-con {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

完整的 DEMO :

See the Pen flexbox 布局中 flex 项中 text-overflow:ellipsis 失效问题 by feiwen8772 (@feiwen8772) on CodePen.0

我们看到 .col2 设置 flex: 1; , .item-con 设置了 text-overflow:ellipsis ,但是文本还是溢出了。

这种布局在移动端页面开发时候经常遇到,我们不能为 .item-con 元素设置个宽度,这样就无法适应不同屏幕尺寸的终端设备。

解决方案:在 flex 项中设置 min-width: 0;

解决方案是在 flex 项(上例子中 .col2 元素)中设置 min-width: 0;,当然你也可以设置其他合适的 min-width 值。

See the Pen flexbox 布局中 flex 项中 text-overflow:ellipsis 失效问题解决方案 by feiwen8772 (@feiwen8772) on CodePen.0

我们看到问题解决了!但是原因呢?

flex 项的宽度计算原理

没兴趣的小伙伴建议不要看了,太绕了,伤脑细胞,查阅了众多资料才理清楚的。

根据 CSS 规范草案,一般情况下 min-width 属性默认值是 0,但是 Flexbox 容器中的 flex 项的 min-width 属性默认值是 auto ,这样能为 Flexbox 布局指明更合理的默认表现。

flex 项的宽度应用顺序

flex-basis 定义了在分配剩余空间之前 flex 项默认的大小。flex-basis: auto 意味着 flex 项会按照其本来的大小显示。flex 项的大小最终由 max-width | min-width 限制的 flex-basis 属性决定。如果 flex 项有 min-width 的限制,那么 flex 项中的内容(content)按照 min-width 值为下限。具体的说如果 flex-basis 的值小于 min-width 那么 flex 项中的内容(content)按照 min-width 值计算。如果 flex-basis 的值大于 min-width 那么 flex 项中的内容(content)按照 flex-basis 计算。 反过来就是 max-width 限制。这个好理解是对吧?

你需要记住这个公式:

content – > width – > flex-basis(由 max-width|min-width 限制)

根据上面的公式,我们可以这么理解 flex 项的宽度计算原则:

  • 如果没有设置 flex-basis 属性,那么 flex-basis 的大小就是 flex 项的 width 属性的大小;
  • 如果没有设置 width 属性,那么 flex-basis 的大小就是 flex 项内容(content)的大小;

这一点很好证明,看 flexboxA 中的代码:

See the Pen flex 项的宽度应用顺序 by feiwen8772 (@feiwen8772) on CodePen.0

我们再来看 flexboxB,flexboxC 中 .item2 都设置了 flex: 1 等价于 flex-grow: 1; flex-shrink: 1; flex-basis: 0%;,其中 flex-grow: 1; flex-shrink: 1; 可以是.item2 自动缩放,.item2 内容周围的空隙不会根据 flex-grow 按比例分配。而 .item1flex-basis 为默认值 auto;,所以周围额外的空袭会根据 flex-grow 按照比例分配。

这里特别要注意,特别容易混淆,flex-basis: 0%; 或者 flex-basis: 0; 百分比表示父 Flex 容器的 main size 属性的百分比。0% 就是表示 flex 项内容周围的空隙不会根据 flex-grow 按比例分配。和 flex-basis: auto 的区别见下图。

flex 项中设置 min-width: 0; 或者 min-width: 1px

接下来我们看看 flex 项中设置 min-width: 0; 或者 min-width: 1px 会发生什么?

flexboxC 中 .item2 都设置了 min-width: 0; 或者 min-width: 1px 那么 flex 项中的内容(content)按照 min-width 值计算。

那么怎么计算呢?

使用 ‘shrink-to-fit’ 算法计算

根据 W3C CSS2.1 规范中的描述,shrink-to-fit 的宽度计算方法与 ‘table-layout’ 特性为 ‘auto’(即自动表格布局)时对于单元格的宽度计算方法类似。大致为:

  • 计算格式化内容时除了发生明确的换行外不发生换行的时首选宽度(preferred width),以及 最小宽度(preferred minimum width)
  • 其次,在这种情况下,找出 可用宽度(available width) ,这个宽度为包含块减去 ‘margin-left’、’border-left-width’、’padding-left’、’padding-right’、’border-right-width’、’margin-right’以及所有相关滚动条的宽度。

综上所述:

shrink-to-fit 的宽度 = min ( max (最小宽度, 可用宽度) , 首选宽度)

关于 shrink-to-fit 的更多资料,请参考 CSS2.1 规范 10.3.5 Floating, non-replaced elements 中的内容。

那么很明显 flexboxC 中 flex 项 .item2 中的内容(content)按照算出来是可用宽度。

flex 项中未设置 min-width

一般情况下 min-width 属性默认值是 0,但是 Flexbox 容器中的 flex 项的 min-width 属性默认值是 auto

flex 项中不设置 min-width ,那么 min-width 属性默认值是 auto。flexboxC 中 .item2 flex 项中的内容(content)尺寸没有 min-width 限制,也就不适用 ‘shrink-to-fit’ 算法,所以 flexboxB 中 .item2 flex 项的宽度为其内容(content)宽度。


如果你觉得本文对你有帮助,那就请分享给更多的朋友
关注「前端干货精选」加星星,每天都能获取前端干货
赞(2) 打赏
未经允许不得转载:WEB前端开发 » [2分钟学个CSS小技巧] flex 项中子元素文本溢出截断 text-overflow:ellipsis 失效问题 – flexbox 布局中 flex 项的宽度计算原理

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

前端开发相关广告投放 更专业 更精准

联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏