前端难点:Flex 布局里「表格/页面撑不满」—— min-height: 0 到底解决什么?
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
前端难点:Flex 布局里「表格/页面撑不满」—— min-height: 0 到底解决什么?
摘要:B 端 Tab + 表格撑不满、双滚动条?根因是 flex 子项默认 min-height: auto。一文讲清布局链怎么修。 专栏:前端难点实战 · 阅读约 6 分钟 · 难度:⭐⭐⭐ 实战场景:Vue3 中大型 B 端后台
一、现象:高度明明设了 100%,内容却溢出或表格高度为 0
某 B 端后台里常见布局:
Layout (height: 100%) └── Tab 栏 └── 查询表单 └── 表格组件(期望撑满剩余空间)
.page { height: 100%; display: flex; flex-direction: column; }
.table-box { flex: 1; height: 100%; }
结果:
- 表格高度变成 0,或只有 minHeight 280px
- 页面出现双滚动条(外层 + 表格内层)
ResizeObserver算出的可用高度不对
二、根因:Flex 子项默认 min-height: auto
CSS Flexbox 规范里,flex 子项的默认 min-height 是 auto,含义是:
子元素的最小高度不能小于其内容的高度。
当子项内容很高(如 el-table 内部 body)时,子项会拒绝收缩,flex: 1 无法把多余空间「让」给滚动区域,布局链断裂。

三、解法:布局链每一层都加 min-height: 0
.layout-box {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden; // 防止外层滚动
}
.content-wrapper {
flex: 1;
min-height: 0; // 关键 ①
display: flex;
flex-direction: column;
}
.tabs-page-content {
flex: 1;
min-height: 0; // 关键 ②
display: flex;
flex-direction: column;
}
.tableBox {
flex: 1;
min-height: 0; // 关键 ③
}
记忆口诀:flex 纵向布局要滚动,从外到内每一层 flex: 1 的节点都要 min-height: 0(横向滚动则用 min-width: 0)。
四、与 ResizeObserver 配合
实际项目 useTable 用 ResizeObserver 计算表格高度:
const getTableHeight = () => {
const parentHeight = parentNode.getBoundingClientRect().height
// 减去兄弟节点(Tab、表单)高度
height.value = Math.max(parentHeight - sum, minHeight ?? 280)
}
若父链路上某层 min-height: auto 导致父高度被内容撑爆,这里读到的 parentHeight 就是错的,表格要么过高要么为 0。
正确顺序:
- 先用 flex +
min-height: 0固定布局链 - 再用 ResizeObserver 微调 el-table 的
height
五、Dialog 封装 弹窗 body 滚动的同一原理
.app-dialog {
display: flex;
flex-direction: column;
max-height: calc(100vh - 48px);
overflow: hidden;
.ep-dialog__body {
flex: 1;
min-height: 0; // 滚动发生在 body 内,不是遮罩层
overflow: auto;
}
}
没有 min-height: 0,弹窗内容会把整个 dialog 撑出视口,出现遮罩层滚动——体验很差。
六、排查清单

七、小结
min-height: 0 不是 hack,而是 flex 子项允许收缩的标准写法。B 端「Tab + 筛选 + 表格满屏」几乎都会踩这个坑,搞懂这一条能少查半天 DevTools。
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。


浙公网安备 33010602011771号