flex-shrink生效是否需固定弹性项宽度?如何让它立即生效?
我十分困惑,为何只有为想要更快收缩的弹性项(flex item)设置固定宽高后,flex-shrink属性才会生效。当前左右列以相同速率收缩,flex-shrink似乎未产生作用。但如果将colLeft和colRight的宽度设为300px,当容器收缩至600px及以下时,flex-shrink才开始生效。
我想了解如何无需设置左列固定宽度,就能让flex-shrink立即生效;若必须为弹性项设置任意宽度,最佳实践是使用px还是em?
附代码:
CSS
*, *::before, *::after { box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -o-box-sizing: border-box; } body { margin: 0; height: 100vh; width: 100vw; border: 2px solid black; } .container { width: 100%; height: 100%; border: 2px solid blue; display: flex; justify-content: center; align-items: center; flex: row nowrap; } .colLeft, .colRight { height: 100%; width: 50%; border: 2px solid red; display: flex; flex-flow: column nowrap; justify-content: space-evenly; align-items: center; align-content: space-around; } .colLeft { flex: 1 10 auto; } .colRight { flex: 1 1 auto; }
HTML
<body> <div class="container"> <div class="colLeft"> 1 </div> <div class="colRight"> 2 </div> </div> </body>
为什么flex-shrink当前未生效?
flex-shrink的收缩比例不是直接按设置的数值生效,而是基于**弹性项的基准尺寸(flex-basis)**计算得出。核心计算公式为:
单个弹性项收缩量 = 总溢出空间 × (flex-shrink值 × 基准尺寸) ÷ 所有弹性项的(flex-shrink×基准尺寸)之和
你当前给两个列设置了width: 50%,同时flex-basis: auto(flex简写的第三个参数默认值),此时flex-basis会继承width的计算结果——也就是容器宽度的50%。由于两个列的基准尺寸完全相同,即便flex-shrink设为10和1,最终收缩量的比例是(10×50%) : (1×50%) = 10:1,但因为初始尺寸同步随容器宽度缩小,视觉上的“收缩速率”感知近似一致,导致flex-shrink的效果不明显。
当设置固定宽度300px后,基准尺寸变为固定值,总溢出空间的计算更明确,flex-shrink的比例直接体现在收缩量上,所以能明显看到差异。
无需固定宽度让flex-shrink立即生效的方法
移除width: 50%,改用flex-basis: 0定义基准尺寸,同时保留flex-grow分配初始空间:
.colLeft, .colRight { height: 100%; /* 移除width:50% */ border: 2px solid red; display: flex; flex-flow: column nowrap; justify-content: space-evenly; align-items: center; align-content: space-around; } .colLeft { flex: 1 10 0; /* flex-grow:1, flex-shrink:10, flex-basis:0 */ } .colRight { flex: 1 1 0; /* flex-grow:1, flex-shrink:1, flex-basis:0 */ }
这样设置后,初始状态下flex-grow:1会让两个列平分容器空间;当容器收缩时,由于flex-basis:0,收缩量的比例直接等于flex-shrink的数值比(10:1),左边会以更快速率收缩,效果立即可见。
固定宽度的最佳实践:px还是em?
- px:适用于需要精确控制尺寸的场景(如固定宽度的侧边栏、图标容器),尺寸不会随字体或系统缩放设置变化,稳定性强。
- em:适合与文本关联的组件(如按钮、卡片、表单控件),尺寸会继承父元素的字体大小,能随字体缩放自适应,提升无障碍访问体验。
如果是布局类弹性项,优先推荐使用flex-basis结合百分比或0实现弹性布局,避免固定宽度;若必须使用固定单位,根据是否需要响应字体变化选择px或em。
内容的提问来源于stack exchange,提问作者chung

