flex-grow: var(--r) 失效主因有三:父容器未设 display: flex;子元素 width 或 flex-basis 抢占空间;CSS 变量值含单位、空格或引号。需内联声明、纯数字值、fallback 语法及 flex-basis: 0 保障比例准确。

flex-grow: var(--r) 为什么总不按预期分配空间
不是变量没传进去,而是计算链在三个地方断了:父容器没设 display: flex、子元素写了 width 或 flex-basis 抢占了剩余空间、变量值带单位或空格(比如 --r: "1.777" 或 --r: 1.777px)。Chrome DevTools 的 Computed 面板里如果看到 flex-grow 解析为 0 或 inherit,基本就在这三类里。
必须用内联 style 注入:style="--r: 1.777",不能靠 data- 属性;变量名要合法(如 --ratio),值必须是纯数字,无引号、无单位、无空格。fallback 写法 flex-grow: var(--r, 1) 很关键——没定义时不会崩布局。
flex-basis 设成 0 还是 auto?决定比例是否“干净”
想让 flex-grow 严格按变量比例瓜分容器宽度,就得切断内容尺寸干扰:flex-basis: 0(注意:不是 0px 或 0%,但旧版 Safari 可用 0% 兼容)。
-
flex: 2 0 0→ 剩余空间 = 容器宽 − 0,全部由flex-grow分配,比例绝对可靠 -
flex: 2 1 auto→ 剩余空间 = 容器宽 − 内容宽度之和,更“自然”但比例被文本/图片原始尺寸悄悄拉偏 - 含图片或内联块的子项,额外加
min-width: 0,防浏览器按固有尺寸撑开
间距用 --space-unit + calc() 而不是 em/rem
直接用 em 或 rem 控制 margin/padding 会因绑定根字体大小而失真:用户缩放、辅助功能开启、横竖屏切换都可能让卡片重叠或按钮溢出。
立即学习“前端免费学习笔记(深入)”;
正确做法是抽一个无单位变量::root { --space-unit: 4; },再在组件里显式乘单位:
button {
margin: calc(var(--space-unit) * 0.5px) 0;
}
.card {
padding: calc(var(--space-unit) * 1px) calc(var(--space-unit) * 2px);
}响应式只需重设变量:@media (min-width: 768px) { :root { --space-unit: 6; } },所有组件间距自动响应,不用改一行具体样式。
兼容性与动态更新的隐藏成本
flex-grow: var(--r) 在 Chrome/Firefox/Safari ≥15.4 支持,Safari ≤15.3 和 IE11 会忽略——必须降级,比如用 JS 检测后 fallback 到固定值,或拆开写 flex-grow: 2; flex-shrink: 0; flex-basis: 0%。
动态改变量后布局卡顿?别直接操作 element.style,优先切 class 或用 CSSStyleSheet.insertRule。真正复杂的点不在“能不能写变量”,而在于 flex-basis 和 flex-grow 协同发生在 layout 阶段早期:一旦内容宽度、box-sizing、内边距没对齐,比例就会无声偏移,且很难在 DevTools 里一眼看出。


















