垂直居中的方法(面试常见)
面试速答(30 秒版 TL;DR)
- 工程首选:
flex/grid。display: flex; align-items: center;display: grid; place-items: center;
- 已知高度的弹层:
top: 50% + translateY(-50%)。 - 单行文本:
line-height = height(仅适用于单行,且对字体/换行敏感)。
常见场景速查表
| 场景 | 推荐写法 | 备注 |
|---|---|---|
| 容器内垂直居中子项 | 父:display:flex; align-items:center | 最常用 |
| 水平+垂直同时居中 | 父:display:grid; place-items:center | 一行解决 |
| 绝对定位弹层垂直居中 | top:50%; transform: translateY(-50%) | 不依赖已知高度(但需要 transform) |
| 单行文本垂直居中 | line-height: <容器高度> | 多行/换行会失效 |
| 兼容老旧布局 | display: table-cell; vertical-align: middle | 需要额外结构或表格语义 |
方案 1:Flex 垂直居中(推荐)
.row {
display: flex;
align-items: center;
}
如果还需要左右居中:
.box {
display: flex;
align-items: center;
justify-content: center;
}
方案 2:Grid place-items: center(更“语义化”的居中)
.box {
display: grid;
place-items: center;
}
方案 3:top: 50% + translateY(-50%)(弹层/气泡常用)
.modal {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
要点:
translateY(-50%)的百分比是相对于自身尺寸,因此可以不依赖已知高度。
方案 4:单行文本 line-height(仅单行)
.btn {
height: 40px;
line-height: 40px;
}
限制:
- 一旦换行或字体度量变化,就容易不居中或溢出。
典型题 & 标准答法
Q1:为什么 vertical-align: middle 不能垂直居中一个 div?
答:vertical-align 主要用于行内格式化上下文(inline/table-cell 等),对普通块级元素不适用;块级元素的垂直对齐通常用 flex/grid 或定位+transform。
Q2:top: 50% 为什么还要 translateY(-50%)?
答:top: 50% 让元素的顶部到父容器顶部是 50%,元素本身还没“扣掉自身高度的一半”;translateY(-50%) 把自身向上拉半个自身高度,才是几何意义上的居中。
易错点/坑
- 移动端
100vh兼容性:地址栏变化会导致视觉高度抖动,垂直居中要注意使用svh/lvh/dvh或业务兜底。 transform会创建新的包含块/层叠上下文:可能影响position: fixed子元素与z-index表现。- 单行
line-height法在多语言与可访问性场景里风险较高(字体度量差异)。
速记要点(可背诵)
- 垂直居中首选 flex/grid;弹层用
top:50% + translateY(-50%);单行文本可用line-height=height。