【面试必问】CSS 水平垂直居中的5种终极方案,收藏这一篇就够了
面试造火箭,工作拧螺丝。但在CSS里,居中这颗螺丝若是拧不紧,UI验收必定过不了。本文抛开花哨的理论,直接上代码,总结5种最硬核、最实用的水平垂直居中方案。
首先定义html,大中包小,小的水平垂直居中
统一 HTML 结构:
Html
<div class="parent"> <div class="child">我是子元素</div> </div>
方案一:现代标准 - 弹性Flex (最推荐)
目前前端开发的首选方案,无副作用,逻辑清晰。
CSS
.parent {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
/* 核心属性仅需以上三行 */
height: 300px;
}
- justify-content: center 水平居中(主轴居中)
- align-items: center; 垂直居中(交叉轴居中)
- 优点:代码简洁,不依赖子元素宽高,兼容性好(IE10+)。
- 适用:95% 的业务场景。
方案二:网格布局 - Grid (最简洁)
如果你追求极致的代码精简,Grid 是王道,两行代码搞定,或者直接将方案一的display:flex 中的flex改为grid。
CSS
.parent {
display: grid;
place-items: center; /* 水平 + 垂直居中 */
height: 300px;
}
- 简单一句话:place-items: center;
- 优点:代码量最少,语义化强。
- 缺点:兼容性略逊于 Flex(主要由于 place-items 属性在部分旧版浏览器支持度一般)。
方案三:万能定位 - Absolute + Transform (不定宽高)
在不使用 Flex/Grid 的前提下,这是处理不定宽高子元素居中的最佳方案。
刚才的都是在父容器的css中定义的,这个是在子容器(也就是要水平垂直居中的容器)的css中定义的,面试时可别记混了位置
给top和left分别一个50%,然后自身再top和left负50%
CSS
.parent {
position: relative;
height: 300px;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 向左上移动自身宽高的50% */
}
- 这是在不知道宽高的情况下,知道的话,就不用使用translate。
- 直接换成margin-top:-100px
- margin-right:-100px
- 这样也就成了方案四
- 优点:无需知道子元素具体宽高,兼容性较好。
- 缺点:transform 可能会导致某些浏览器下的字体/像素模糊(非整数像素渲染),且元素脱离文档流。
方案四:定宽高定位 - Absolute + Negative Margin (传统方案)
在 IE8/9 时代的主流方案,前提是必须知道子元素的宽高。
CSS
.parent {
position: relative;
height: 300px;
}
.child {
width: 100px; /* 必须定宽 */
height: 100px; /* 必须定高 */
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px; /* 高度的一半 */
margin-left: -50px; /* 宽度的一半 */
}
- 优点:兼容性极强(IE6+)。
- 缺点:灵活性差,子元素宽高改变需修改 CSS,维护成本高。
方案五:行内块法 - Text-align + Vertical-align (伪元素法)
利用 inline-block 的特性,常用于多行文本或图片居中,需要一个“幽灵元素”辅助。
CSS
.parent {
text-align: center; /* 水平居中 */
height: 300px;
/* 消除间隙 */
font-size: 0;
}
/* 构造一个高度100%的伪元素支撑 */
.parent::before {
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
}
.child {
display: inline-block;
vertical-align: middle; /* 垂直对齐 */
font-size: 16px; /* 恢复字号 */
}
- 适用:PC端老旧项目重构,或特殊的图文混排场景。
- 缺点:代码Hack味道重,需要处理 inline-block 带来的空白字符间隙问题。
总结与对比
不做选择题,根据场景直接套用:
| 方案 | 核心技术 | 是否需定宽高 |
|---|---|---|
| Flexbox | flex + justify/align | 否 |
| Grid | grid + place-items | 否 |
| Transform | absolute + translate | 否 |
| 负Margin | absolute + margin | 是 |
| 伪元素法 | inline-block + vertical-align | 否 |
一句话建议:新项目无脑上 Flex,追求极简上 Grid,维护老项目看情况用 Transform。
NEXTO6