flex-1的行为与预期不符
先看这么一个例子
html
<div className='h-40 w-40 border-black border border-solid flex'>
<span className='flex-none'>横向</span>
<div className='flex-1'>
<div className='h-full w-80 bg-blue-300'></div>
</div>
<span className='flex-none'>横向</span>
</div>
预期效果是span站两边 div填充剩余空间
但实际结果是这样的 中间的div会被子元素撑开 而不是恰好占据剩余空间
原理和解决
flex:1
=== flex: 1 1 0%
=== flex-shrink: 1
+flex-grow: 1
+flex-basis: 0%
但dom的宽度不是由flex-basis单独决定的
由于有w-80
的子元素 本该宽度自适应的容器也被撑开(flex-auto也一样)
设置overflow为hidden或auto可以解决这个问题
这是因为此时的父容器创建了一个bfc 使得自身宽度的计算不会受到子元素影响
更进一步的探索
bfc可以解释目前的结果 但是也存在一个瑕疵:
display:flow-root
也能创建bfc 而它不能解决这个问题
对此 ai的回答是
仅供参考
实际场景
在实际场景下 还会遇到多个flex-1的嵌套(不然就不会有这篇文章了)
html
<div className='w-60 h-40 pb-4 flex border-red-400 border border-solid'>
<span>11</span>
<div className='flex-1 border-black border border-solid flex'>
<span className='flex-none'>横向</span>
<div className='flex-1 overflow-auto'>
<div className='h-full w-80 bg-blue-300'></div>
</div>
<span className='flex-none'>横向</span>
</div>
<span>22</span>
</div>
设置了overflow:auto
依旧不能完美自适应
hidden也不行
原因是内侧的flex-1容器创建了bfc 宽度不受子元素影响 但外侧的flex-1没有 还是会被撑开
如上图所示 可以看到内侧(黑框)没有被撑开 而外侧(红框)被撑开了
所以最正确的写法是
html
<div className='w-60 h-40 pb-4 flex border-red-400 border border-solid'>
<span>11</span>
<div className='flex-1 border-black border border-solid flex'>
<span className='flex-none'>横向</span>
<div className='flex-1 relative'>
<div className='absolute inset-0 overflow-auto'>
<div className='h-full w-80 bg-blue-300'></div>
</div>
</div>
<span className='flex-none'>横向</span>
</div>
<span>22</span>
</div>
就会两招 flex布局
和position定位
再掏也就这两样 没活了 连三板斧都凑不齐
不过大部分问题都不需要什么别的东西 靠这两招莽过去就行了
我实在不敢用优雅去挑战自己的耐心、细心和工期(以及同事的技术)