max-height 必须配合 overflow 才生效,单独设置无效;应将 max-height 和 overflow-y: auto 应用于内容区(如 .modal__body),而非弹窗根元素;需注意 flex 布局、软键盘导致的 vh 失准、滚动穿透等问题。

max-height 必须配 overflow 才生效
只写 max-height: 60vh 是没用的——溢出内容照样突破容器,页面布局会崩。真正起作用的是组合:max-height 定上限,overflow: auto 或 overflow: hidden 控制溢出行为。
常见错误是给弹窗根元素(比如 .modal)设了 max-height,但忘了它内部的 .modal__body 可能用了 height: 100% 或 flex: 1,结果子容器把父容器撑爆。解决办法是把 max-height 和 overflow 都落在内容区上:
.modal__body { max-height: 60vh; overflow-y: auto; }- 避免在
.modal上直接设height或min-height百分比,容易和max-height冲突 - 移动端必须加
-webkit-overflow-scrolling: touch,否则 iOS 滚动卡顿、回弹失效
用 vh 还是 rem?优先选 vh,但要防极端情况
max-height: 70vh 看起来直观,但它依赖视口高度,而某些安卓浏览器或微信内置 WebView 在软键盘弹出时会把 vh 算错——原本 800px 的视口可能缩到 400px,导致弹窗被压扁。
更稳妥的做法是混合使用:
- 基础值用
max-height: calc(100vh - 120px),预留顶部状态栏 + 底部操作区空间 - 再加一层兜底:
max-height: 600px,防止大屏平板撑太开 - 不单独依赖
rem,因为字号缩放不影响高度约束,容易误判实际可用空间
Flex 布局下 max-height 失效?检查 display 和 flex-direction
Element UI 或自定义弹窗常用 display: flex + flex-direction: column 排版,这时如果给整个弹窗容器设 max-height,它往往不生效——因为 flex 容器默认会拉伸子项去填满高度,无视 max-height。
正确做法是把高度约束“下沉”到具体滚动区域:
- 确保
.modal__body是 flex 子项,且设flex: 1或flex: 1 1 auto - 在这个子项上直接设
max-height和overflow-y: auto - 别给
.modal__header或.modal__footer设flex-shrink: 0以外的弹性属性,否则它们会抢走空间
遮罩层滚动穿透导致高度失控?先锁 body 再控弹窗
弹窗一打开,背景页还在滚动,用户一划就触发页面滚动,弹窗位置偏移、高度计算错乱——这不是弹窗本身的问题,是底层 body 没锁住。
必须同步处理两件事:
- 弹窗显示时:
document.body.style.overflow = 'hidden'; document.body.style.height = '100vh'; - 同时给弹窗遮罩层加
overscroll-behavior: contain;,防止手指滑到边缘时穿透到底层 - 关闭弹窗后,记得还原
body的overflow和height,否则后续页面无法滚动
真正难的不是写对那几行 CSS,而是得记住:弹窗高度从来不是孤立存在的,它和视口变化、软键盘、滚动锁、flex 布局层层咬合。每次改完,至少在真机 Safari 和微信安卓里点开软键盘再试一遍。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











