CSS 水平垂直居中的五种方式

1 阅读3分钟

【面试必问】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 带来的空白字符间隙问题。

总结与对比

不做选择题,根据场景直接套用:

方案核心技术是否需定宽高
Flexboxflex + justify/align
Gridgrid + place-items
Transformabsolute + translate
负Marginabsolute + margin
伪元素法inline-block + vertical-align

一句话建议:新项目无脑上 Flex,追求极简上 Grid,维护老项目看情况用 Transform

NEXTO6