外观
如何让一个元素水平垂直居中?
不确定尺寸时,用 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等于高度只适合单行文字,按钮里的图标会偏。