必须同时设置display: flex、justify-content: center和align-items: center,且父容器需有明确高度(如min-height: 100vh),否则align-items在交叉轴无尺寸时静默失效;子元素不能为position: absolute或float,否则脱离文档流。

display: flex + justify-content/align-items 必须配 height
最简写法就是三行 CSS:display: flex、justify-content: center、align-items: center,但没加 height: 100vh 或 min-height: 100vh 就等于白写。
常见错误现象:写了 flex 居中却完全没反应——90% 是因为父容器(比如 或外层 <div>)没设高度,而默认是“内容撑开”,交叉轴(垂直方向)无尺寸,<code>align-items: center 静默失效。
-
上直接用要先清默认 margin:body { margin: 0; } - 推荐用
min-height: 100vh而非height: 100vh,避免内容超长时被截断 - 子元素不能是
position: absolute或float,否则脱离文档流,flex 不再管它 - 如果父容器有
flex-direction: column,justify-content控制的是垂直方向,align-items反而控制水平方向——别记反
position: absolute + transform: translate(-50%, -50%)
兼容性更好,尤其适合要支持 IE11 或老版 Safari 的项目。写法固定,但漏掉任一条件就会偏移。
关键点不是“写对 transform”,而是整个坐标系是否成立:
- 父容器必须设
position: relative(或absolute/fixed),否则top: 50%和left: 50%会相对于 viewport 定位,直接飞出屏幕 -
transform: translate(-50%, -50%)的百分比基于元素自身宽高,所以不依赖尺寸是否固定 - 如果子元素本身已有
transform: scale(1.2)或rotate(15deg),必须合并写:transform: translate(-50%, -50%) scale(1.2),否则顺序错乱导致中心偏移 - 在频繁动画场景下(如
will-change: transform),这个方案比 flex 触发更多重排重绘
margin: auto 配合四边定位容易失效
看着最简洁:position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto;,但实际限制多、行为不稳定。
它靠浏览器自动计算 margin 居中,只在特定条件下生效:
- 子元素必须有明确的宽高(
width和height不能是auto) - 某些旧版安卓 WebView 对该行为支持不一致,同一段代码在不同机型上可能一个居中、一个贴左上角
- 如果父容器设置了
overflow: hidden或transform,可能干扰 margin 计算逻辑 - 它不适用于 flex 或 grid 子项——这些容器里
margin: auto行为完全不同
Grid 的 place-items: center 最语义化但兼容性有缺口
一行 place-items: center 就能同时搞定水平垂直居中,且天然支持响应式和多子元素布局,但 IE 完全不支持,Edge 16–18 也有 bug。
适用前提是:你确定不需要兼容 IE,且父容器本身就是 grid 容器(display: grid)。
- 不用设高度也能工作,只要网格轨道(grid track)有尺寸(比如
grid-template-rows: 1fr) - 如果只想要单个子项居中,
place-items比分别写justify-items和align-items更简洁 - 注意:它会影响所有子项;若只想居中某一个,得用
justify-self+align-self - 在 Safari 14.1 之前,
place-items对subgrid支持不完整,慎用于嵌套网格











