全屏loading垂直居中必须设父容器明确高度;仅display: flex+align-items:center+justify-content:center无效,因flex需可计算交叉轴空间,应使用min-height: 100dvh(或height: 100vh)并确保子元素为直接子节点。

全屏Loading的父容器必须有明确高度
只写 display: flex; align-items: center; justify-content: center 是没用的——Flex 不会凭空造出“垂直空间”。如果父容器高度是 auto(比如默认的 body),那它的实际高度就是内容撑开的几像素,align-items: center 根本无处发力。
常见错误现象:Loading 图标紧贴顶部,DevTools 里看到父容器高度为 0px 或远小于视口。
- 给父容器设
min-height: 100dvh(推荐),降级 fallback 写height: 100vh;后者在旧浏览器生效,前者在 Chrome 120+/Safari 17.4+/Firefox 115+ 动态适配地址栏/键盘变化 - 别用
min-height: 100vh—— 它只保底,不提供对齐所需的确定交叉轴长度 - 如果加在
body上,iOS Safari 和微信 X5 内核可能忽略,建议包一层<div class="loading-overlay"> <li>避免直接在 <code>html或body上写display: flex,容易和全局 reset、第三方库冲突 - 如果子元素是未设尺寸的
<svg></svg>、纯文字或inline元素,margin: auto直接失效 - 某些安卓 WebView 和 Chrome 80 以下版本会完全忽略该写法
-
flex方案不依赖子元素尺寸,哪怕里面只有一行Loading...也能稳居中央 - 稳妥写法:
height: 100vh; height: 100dvh;(后者覆盖前者) - 老版 Safari(如 iOS 15.6)需 JS 补偿:
document.documentElement.style.height = window.innerHeight + 'px',并在resize和keyboarddidshow事件中更新 - 千万别用
inset: 0配合position: fixed当高度替代方案——它不提供交叉轴长度,align-items仍无效 -
align-items只对 Flex 容器的**直接子元素**生效,absolute元素已脱离文档流,完全不受控制 - 确保 Loading 图标本身是
flex容器的直接子节点,不要嵌套多层position: relative包裹 - 如果必须加关闭按钮,把它也作为 Flex 子项,用
margin-left: auto推到右上角,而不是absolute
为什么不能只靠 position: fixed + margin: auto?
有人试过 position: fixed; top: 0; left: 0; right: 0; bottom: 0; margin: auto;,发现 Loading 文字或 SVG 依然贴顶。这不是 bug,是机制限制:margin 自动居中只在元素有**明确宽高**且容器有可计算剩余空间时才触发。
移动端必须用 100dvh,不是 100vh
iOS Safari 地址栏收起/弹出、Android 键盘唤起时,100vh 会跳变(比如从 812px 突然缩到 600px),导致 Loading “上蹿下跳”。100dvh 是动态视口单位,能实时响应这些变化。
子元素用了 absolute 就脱离 Flex 流程
如果 Loading 层里有个关闭按钮用了 position: absolute,或者蒙层用了 background: rgba(...) 但没设 z-index 导致层级错乱,都可能让你误以为居中失效。
最易被忽略的是:写了 align-items: center 却漏了 justify-content: center。默认 flex-direction: row 下,前者管垂直,后者管水平——少一个,就只居中一个方向。这问题在调试时很难一眼看出,尤其当容器背景色和页面一致时。











