Skip to content

如何让一个元素水平垂直居中? ​

不确定尺寸时,用 flex 或 grid。已知要居中的是单个块,也可以用绝对定位配合 transform。行内文字才用 line-height 去凑垂直位置。

原理 ​

Flex。 父元素成为弹性容器,两条轴都居中:

css
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100%;
}

父元素自己要有高度,否则垂直方向没有空间可分。页面正中时,高度经常是 100vh 或传到 html, body 的 height: 100%。

Grid。 一行搞定两条轴:

css
.parent {
  display: grid;
  place-items: center;
  min-height: 100%;
}

绝对定位。 不要求父元素是 flex。父元素要 position 不是 static:

css
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

top/left: 50% 把子元素的左上角放到中心,translate(-50%, -50%) 再往回挪自身宽高的一半,所以宽高未知也可以。

子元素宽高已知时,还可以四边拉满再让 margin 平分:

css
.child {
  position: absolute;
  inset: 0;
  width: 200px;
  height: 80px;
  margin: auto;
}

单行文字可以把 line-height 设成容器高度,再 text-align: center。多行、包含块级子元素时不要用这招。

追问 ​

居中之后还要响应式吗?

Flex 和 grid 的方案不依赖子元素尺寸,窗口变了仍然居中。绝对定位方案也一样,只要百分比和 translate 还在。写死 margin 或 line-height 的方案,内容一换行就偏。

transform 居中会不会影响布局?

transform 在布局之后,不改变文档流里占的位置。周围元素不会因为它视觉上挪了而重新避让。

易错点 ​

  • 只给子元素 margin: 0 auto 只能水平居中,而且子元素需要有宽度、是块级。
  • 父元素没有高度时,三种方案在垂直方向都没有参照。
  • line-height 等于高度只适合单行文字,按钮里的图标会偏。

相关 ​