跳到主要内容

垂直居中的方法(面试常见)

面试速答(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