Flex布局中一个不为人知的特性
共 1764字,需浏览 4分钟
· 2021-09-11
关于本文要说的这个特性,我之前也不清楚,还是遇到问题之后,阅读规范才知道的,故事是下面这样的:
某日被告知有一个bug:在网页宽度较小时,发现 Flex
容器被子元素撑大导致UI显示异常的问题,如下:
![](https://filescdn.proginn.com/290c08644a36c2644a58d920bb9b7fec/43e910d3b1134f2dbf3f0599d970d557.webp)
这是什么鬼...我期待它不管什么时候都能像下面这样显示(不撑破父容器):
![](https://filescdn.proginn.com/c0f91a1894bb8c18ef5cde6e9bf95038/3e46b72d20d64c8110ba767f931a2f55.webp)
我开始一顿操作猛如虎,各种审查元素样式,恕我愚钝,并没有看出什么问题,看起来似乎都很正确的样子....
当然,浏览器是不会骗我的,虽然,不知道哪里出了问题,但是这并不影响我修复这个问题。我试了试,发现加个 flex
容器加个 overflow:hidden
属性之后,完美解决问题。然后又试了试,发现加 min-width: 0
也可以解决这个问题。
bug 改好了,但是不知道为什么加个 overflow:hidden
或者 min-width: 0
就好了。
![](https://filescdn.proginn.com/13bb2b2b39d0c1cf439926ba64e832ca/b89498bac669697910c57480d5293d82.webp)
想来我非常普通的CSS水平可能无法解开这一难题,于是我开始思考朋友圈哪位大佬对CSS颇有研究,于是我就写了个最简的Demo,然后微信去请教了下大佬,大佬跟我说:原理说起来可就复杂了,然后分享我一篇文章链接。我看完之后,发现对我的问题并没有一个非常好的解释,于是又继续厚着脸皮问了,大佬说这块可能他也没有覆盖到。
好嘛,毕竟是周五,也不好一直骚扰大佬,于是,我就继续自己寻找答案。其实写最简Demo的时候,我发现了一个小小问题,那就是:其实这个问题出现在 Flex
嵌套之中,如果不是嵌套的话,那么 Flex
容器并不会被 Flex
的项目撑破。可以戳这个查看最简Demo:https://codepen.io/yvettelau/pen/OJWMdoM?editors=1100
![](https://filescdn.proginn.com/34d245dc22f1bb03fca83f4b6054f3e6/778b444f52124a9c3cd3cb1899f3aa58.webp)
如果我们删除掉 div class=main
那一层,那么表现良好,即每个 item
都按照预期缩小了。
![](https://filescdn.proginn.com/e429765d3187f703e20730d562abbd99/24e3e7c805dbc139354b1b52ed857323.webp)
然鹅,还是不知道原因吖,搜索引擎找了一番也没找到什么有说服力的答案,于是,我决定研究一下 flex
的规范(https://www.w3.org/TR/css-flexbox-1/#min-size-auto),看到如下一段话:
![](https://filescdn.proginn.com/3d6c6166b6fc2eec582a9396c7126e43/71bafb7570198538d50f70f3f64510cf.webp)
通过阅读标准,可以发现:
在非滚动容器中,主轴方向Flex Item
的最小尺寸是基于内容的最小尺寸,此时 min-width
的值是 auto
。对于滚动容器,min-width
的值是 0(默认讨论水平布局)
读到这里,我意识到这个问题跟Flex嵌套应该没什么关系,不嵌套应该也一样存在这个问题,于是我又新写了个demo,可以戳这个查看:https://codepen.io/yvettelau/pen/poRgYPK?editors=1100
![](https://filescdn.proginn.com/322c8c0bb96c80c24ae1df4a35767bf2/2d3f977ef8fa42c1cd13045add6619ae.webp)
当 item
的内容 child
宽度是250px时,此时也不能按照预期缩小。可能这个时候,第一反应是给 item
加 flex-shrink
,然而并木有用。—— 当 min-width
是 auto
时,其最小尺寸是基于内容的,加 flex-shrink
是没有作用的。
这个时候就乖乖按照规范教的操作吧,例如,我们给 item
设置 min-width:0
,这个时候,item
会按照预期缩小,平分500px的大小。
![](https://filescdn.proginn.com/4a4d650cf4f6b65a135885bcada5f680/2bcb57755cd5b793510afa084b9b3b42.webp)
另外,规范也说明了在滚动容器中,min-width
也是0,所以,给 item
增加 overflow: auto
或者 overflow: hidden
也一样可以达到目的。
现在,我们再回过头来看文章最开始的问题。看起来是 Flex
嵌套导致的问题,其实是因为嵌套在里面的 div
,它不仅仅是 Flex
容器,同时它也是一个 Flex Item
。因此,我们可以给它加上 overflow: hidden
或者是 min-width: 0
来阻止它撑破父容器。
最后的最后,吐槽一句,CSS真是太复杂了...
参考链接:
https://www.w3.org/TR/css-flexbox-1/#transferred-size-suggestion 还有一个忘记保存链接的stackflow