父容器必须有明确高度且子元素不能脱离文档流才能实现 flex 垂直水平居中;推荐 min-height: 100vh 或 100dvh,清除 body 默认 margin,并避免 float、absolute 等导致子元素退出 flex 上下文。

直接写 display: flex + justify-content: center + align-items: center 就能实现,但多数失效不是代码写错,而是父容器没撑开高度或子元素脱离了文档流。
父容器必须有明确高度,否则垂直居中无效
flex 的 align-items: center 是在交叉轴“可用空间”内居中,如果父容器高度塌陷(比如只靠内容撑开),那交叉轴长度就是 0,自然无法居中。
- 推荐用
min-height: 100vh或min-height: 100dvh(后者对移动端地址栏收起/展开更稳) - 避免只写
height: auto或完全不设高——块级元素默认高度由内容决定,不是视口高度 - 若父容器是 body,记得清掉默认
margin:body { margin: 0; min-height: 100vh; }
子元素不能脱离文档流,否则不参与 flex 排列
justify-content 和 align-items 只对 flex item 生效,而 float、position: absolute、position: fixed 都会让元素退出 flex 上下文。
- 检查子元素是否意外加了
float: left或position: absolute - 常见坑:弹窗遮罩层用了
position: fixed,结果里面又套了个 flex 容器——没问题;但如果把子内容也设成position: absolute,它就不再是 flex item 了 - inline 元素(如
<span>)默认是 flex item,但若内容换行或受 white-space 影响,建议显式加display: block避免行为异常
移动端和 IE10–11 的兼容性细节
现代浏览器基本无问题,但老版本或特定场景下仍有表现差异。
立即学习“前端免费学习笔记(深入)”;
- IE10–11 中,
align-items: center对<table>或设置了min-height的子元素支持不稳定,可临时改用flex-direction: column+justify-content: center模拟 - iOS Safari 里
100vh在地址栏切换时会跳变,优先用100dvh;不支持则 fallback 到 JS 动态设style.height - 别忽略
user-scalable=no或强制 zoom,它们会让vh单位计算失准,导致视觉偏移
别混用绝对定位和 flex 居中
有人给父容器同时加 position: absolute 和 display: flex,再给子元素加 position: absolute + margin: auto,这既冗余又不可靠。
-
margin: auto在绝对定位下只对left/right有效,top/bottom不生效(Safari 尤其明显) - 如果父容器必须绝对定位(比如全屏遮罩),它的子容器直接设
display: flex即可,不需要再干预子元素定位 - 纯 flex 方案少写 4 行 CSS,也不用操心 z-index、层叠上下文或 transform 坐标系转换
真正容易被忽略的,是父容器高度是否真实存在——Computed 样式里看 height 或 min-height 是否生效,比反复调 justify-content 更有效。


















