全屏弹窗用 display: flex 垂直居中必须确保父容器有明确高度(如 100dvh)且不塌陷,否则 align-items: center 失效;常见原因包括父容器无 height、position: fixed 未设 inset、body 直接 flex 不兼容、子元素 absolute 脱离流、误用 100vh 导致视口变化抖动等。

全屏弹窗用 display: flex 垂直居中,必须让父容器有明确高度且不塌陷,否则 align-items: center 会失效——这不是 Flex 写错了,是高度没给到位。
为什么 align-items: center 在弹窗里不生效?
常见错误现象:align-items: center 写了,但弹窗内容紧贴顶部;DevTools 里看父容器高度是 0px 或远小于预期。
- 父容器没设
height或min-height,仅靠display: flex不会自动撑高 - 用了
position: fixed但忘了给父容器设inset: 0或top/bottom/left/right: 0,导致它脱离文档流后无尺寸基准 - 在
<body>上直接写display: flex—— 微信 X5 内核和部分 iOS Safari 会忽略,建议包一层<div class="modal-root"> - 子元素用了
position: absolute(比如蒙层上的关闭按钮),它已脱离 flex 流程,align-items对它无效
移动端必须用 100dvh 而不是 100vh
iOS Safari 地址栏收放、Android 键盘弹出时,100vh 会跳变(比如从 812px 突然缩到 600px),造成弹窗“上蹿下跳”。100dvh 是动态视口单位,2026 年主流浏览器(Chrome 120+、Safari 17.4+、Firefox 115+)已支持。
- 稳妥写法:
height: 100dvh,降级 fallback:height: 100vh; height: 100dvh(后者覆盖前者) - 老版本 Safari(如 iOS 15.6)需 JS 补偿:
document.documentElement.style.height = window.innerHeight + 'px',并在resize和keyboarddidshow事件中更新 - 别用
min-height: 100vh—— 它只保底,不提供对齐所需的确定交叉轴长度
Flex 居中要同时写 justify-content 和 align-items
只写 justify-content: center 是水平居中,不是垂直。默认 flex-direction: row 下,主轴是水平,交叉轴才是垂直。
立即学习“前端免费学习笔记(深入)”;
- 正确组合:
justify-content: center; align-items: center; - 如果误写了
flex-direction: column,那justify-content: center才管垂直,align-items: center反而管水平——这容易绕晕,不推荐为居中强行改方向 - 微信 Android(X5 内核)初次渲染可能漏掉
align-items,加一层min-height: 1px到父容器可强制重算交叉轴尺寸
避免与 transform 或 margin: auto 混用
弹窗内部若同时存在 transform: translate(-50%, -50%) 或子元素设了 margin: auto,会和 Flex 的对齐逻辑冲突,尤其在 Safari 中表现为偏移或抖动。
- Flex 容器内,子元素别再写
margin-top: auto—— 它和align-items: center语义重复且优先级混乱 - 不要在同一个元素上既用
display: flex又用position: absolute+transform,选一种方案到底 - 如果弹窗内容高度不确定(比如多行文案),
align-items: center仍可靠;但若用top: 50%; transform: translateY(-50%),就得额外处理高度计算,风险更高
最易被忽略的点:不是 Flex 不行,而是父容器高度来源不可靠。真机测试时,务必关掉地址栏、唤起键盘、横竖屏切换——很多“居中失败”只在这些场景下暴露。

















