前言
就在大大前天(昨天、前天、大前天)晚上的 12:35 ,同事在群里发了一篇文章,关于如何解决 Flex 溢出问题的指南。
原谅写了好几天 T T,最近时间紧、任务重,同时要查的东西比较多。
原文地址: Minimum Content Size In CSS Flexbox - CSS FlexBox 中的最小内容尺寸
这篇文章简单说了 Flex 如何解决文字导致的元素溢出 Flex 父元素的问题。
这时我才意识到,很多兼职前端不是特别清楚 Flex 到底是怎么工作的,为什么会有这种奇怪的问题?为什么我的 flex-grow: 1
并没有解决问题?
于是,便有了这篇文章,这篇文章旨在说明 Flex
出现该问题的核心及原理。
正文
上面那篇文章我不做详细的翻译了,只简单说明下它讲的内容。开篇第一句:
If a flex item has a text element or an image that is bigger than the item itself, the browser won’t shrink them. That is the default behavior for flexbox.
如果 Flex Item
有一个 text
或者 img
子元素比 Flex Item
还要大,浏览器不会将他们缩小。这是 Flex Box
的默认行为。
这句话很好理解,Flex
内的子元素如果是文本或者图片,会超出 Flex Box
的范围。
溢出效果展示
问题:文字溢出
我上面写的示例中,如果你的 span
标签的文字超出了长度限制,那么当前的 span
元素的长度会超出限制,进而导致 Flex Box
的溢出行为。
解决方案
通常情况下的文字宽度溢出,我们可以通过添加 CSS
的 overflow-wrap: break-word;
属性添加换行解决文字溢出问题,但你如果使用 Flex Box
你就会发现这种方式失效了。
问题原因请看下一章节,解决方案只需要两行代码。
min-width: 0;
overflow-wrap: break-word;
完整代码:
问题:图片溢出
我上面写的示例中,如果你的 img
标签的图片宽度超出了父元素的宽度,那么当前的 img
元素的长度会超出限制,进而导致 Flex Box
的溢出行为。
解决方案
解决方案和文字溢出相同,只不过图片我们不再需要添加 overflow-wrap: break-word
来实现换行了。
问题原因请看下一章节,解决方案只需要一行代码。
min-width: 0;
完整代码:
问题原因
先说总结:
我们的 span
标签的 min-width
属性为 auto
。在 Flex Box
中,这样的设置会让元素的最小宽度为内部文字的宽度。
该章节后续的内容基本都是讲该操作的原因,基于个人兴趣选择观看即可。
下面我们一点点讲为什么会产生这种结果。
min-width 、 min-height 的值 auto 的来源
为了方便大家理解,这里需要先讲一下 min-width
、 min-height
的来源。
在早期版本的 CSS
中,min-width
是没有 auto
参数,在 CSS2.1
中,为了给 Flex 提供更合适的默认最小尺寸才引入了 auto
。
在这个版本之前, min-width
的默认值是 0
,它通常没什么意义。在常规的块级元素上它的值就是 0
。因为在常规的块级元素上, min-width: 0
表示元素的最小宽度由其内容和内边距决定。
同时,我们也不可以显式的使用 min-width
,因为 CSS
此时并没有提供该属性,仅是内部属性由浏览器内核决定。
文档地址:CSS Flexible Box Layout Module Level 1
在常规块级元素上,你设置为0
或者auto
实际上对该元素没有影响。
Flex 为什么需要 min-width 等属性?
常见的例子:
- 文字溢出(就是上面的例子)
.flex-container {
display: flex;
}
<div class="flex-container">
<div class="flex-item">This is some long text content.</div>
</div>
- 弹性布局灵活度受限(在没有
min-width
时,子元素无法自由调整宽度)
.flex-container {
display: flex;
}
<div class="flex-container">
<div class="flex-item">Item 1</div>
<div class="flex-item">Item 2</div>
</div>
因此,在布局开始多样性的前提下,CSS2.1
引入了 min-width
min-width: auto 在 Flex Box 中的影响,它在上面代码中意味着什么?
在 FLex Box
中, 它的默认值就是 auto
,min-width: auto
使得元素的最小宽度不再是默认的 0
,而是根据内容和上下文来计算。即使元素没有设置显式的最小宽度,也会有一个最小宽度,以防在 Flex Box
中过于压缩。
在 Flex Box
中的元素设置该参数后,会导致该元素的子元素的最小宽度是根据内部实际内容计算出来的宽度,导致我们的内部元素最小宽度会被设置为它内部的文字的宽度,进而导致溢出问题。
提示
通常情况下,你也可以通过设置 width: 0; flex-grow: 1;
来解决该问题。
这里 width: 0; flex-grow: 1;
生效的原因如下:
通常我们单独设置 flex-grow
时,它无法生效,因为它受 min-width: auto
的影响。
但是显式的声明 width: 0
会覆盖默认的最小宽度(默认的最小宽度优先级不如显式声明 width: 0
的层级高)。
进而让我们的 flex-grow
设置可以生效。
在部分浏览器中(如:FireFox)可能会失效,失效后可能可以通过设置
overflow
不为visible
来解决,也可以通过min-width
解决。
但由于我这里不需要兼容、也没有 FireFox 做过测试,因此我不能保证准确性。
因此,我这里还是推荐使用 min-width
一劳永逸。
写在最后
文章创作不易,该文虽然不长,也是一个简单的小技巧,但完善确实耗费了很多精力。
感谢大家一键三连(点赞、收藏、评论~)
接下来还会持续创作高质量的文章,欢迎大家 点点关注~