CSS专题之水平垂直居中

article/2025/6/24 14:14:34

前言

石匠敲击石头的第 16 次

在日常开发中,经常会遇到水平垂直居中的布局,虽然现在基本上都用 Flex 可以轻松实现,但是在某些无法使用 Flex 的情况下,又应该如何让元素水平垂直居中呢?这也是一道面试的必考题,所以打算写一篇文章来好好梳理一下,如果哪里写的有问题欢迎指出,不胜感激。

分类

实现元素水平垂直居中的方法有很多,大致可以分为以下两类:

  • 固定宽高元素适用的方法
  • 不固定宽高元素适用的方法

我们先实现基础的布局,然后再分别讲每一类具体的方案。

.container {border: 1px solid red;width: 300px;height: 300px;
}.box {background: blue;color: #fff;
}.size {width: 100px;height: 100px;
}
<div class="container"><div class="box size">你好,世界</div>
</div>

在这里插入图片描述

固定宽高元素

absolute + 负 margin

.container {/* 其它的基础样式... */position: relative;
}.box {/* 其它的基础样式... */position: absolute;top: 50%;left: 50%;margin-left: -50px;margin-top: -50px;
}

该方案的原理非常简单,可以分为两步来看:

  1. 先通过绝对定位top: 50%left: 50% 使元素的左上角定位在 .container 容器元素的中心位置

    在这里插入图片描述

  2. 再通过 margin-topmargin-left 设置为负值,具体值为元素宽度和高度的一半,例如这里元素的宽高都是 100px,所以一半就是 50px

    在这里插入图片描述

    最终的效果如下

    在这里插入图片描述

在线查看效果

✅ 优点: 兼容性好,适用于 IE 等老版本浏览器。

⚠️ 缺点:

  • 需要提前知道元素大小,并且需要手动计算元素大小的一半
  • 每次修改元素大小都需要同步修改 margin

absolute + margin: auto

.container {/* 其它的基础样式... */position: relative;
}.box {/* 其它的基础样式... */position: absolute;top: 0;left: 0;right: 0;bottom: 0;margin: auto;
}

该方案和前一个方案最终效果是一样,该方案的步骤如下:

  1. 通过设置绝对定位 top:0; bottom:0; left:0; right:0;,让浏览器知道元素被限制”在父容器内四边,这样有了一个明确的空间范围
  2. 再通过设置 margin: auto,浏览器就可以根据 父容器大小 - 元素大小 = 剩余空间,把剩余空间平分给 margin: auto,实现水平垂直方向上的居中

在线查看效果

✅ 优点:

  • 兼容性好,适用于 IE 等老版本浏览器
  • 每次修改元素大小不需要同步修改 margin 值,无需手动计算元素大小的一半

⚠️ 缺点: 只能用于固定尺寸的元素,不适合宽高不确定的情况。

absolute + calc

.container {/* 其它的基础样式... */position: relative;
}.box {/* 其它的基础样式... */position: absolute;top: calc(50% - 50px);left: calc(50% - 50px);
}

该方案与前面的 absolute + 负 margin 方案原理相同,使用了 calc 函数替代了 margin 负值来计算居中的位置。

在线查看效果

⚠️ 缺点:

  • 该方案依赖 calc 函数的兼容性,具体兼容性可以参考 Can I use
  • 需要提前知道元素大小,修改元素大小需要同步修改 calc 函数中减去的值
  • 相比前两个方案,该方案既缺乏兼容性(IE9+),又需要手动计算元素大小的一半,不推荐使用

不固定宽高元素

absolute + transform

.container {/* 其它的基础样式... */position: relative;
}.box {/* 其它的基础样式... */position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);
}

该方案与前面的 absolute + 负 margin 方案原理相同,使用了 transform 替代了 margin 负值来计算居中的位置。

因为translate(-50%, -50%) 的百分比是相对于元素本身的宽高,所以不需要提前知道元素的具体尺寸。

在线查看效果

✅ 优点: 无需提前知道元素大小,修改元素大小不需要同步修改相关的值

⚠️ 缺点: 该方案依赖 transform() 函数的兼容性,具体兼容性可以参考 Can I use

line-height

.container {/* 其它的基础样式... */line-height: 300px;text-align: center;
}.box {/* 其它的基础样式... */display: inline-block;vertical-align: middle;line-height: initial;
}

该方案的实现步骤如下:

  1. 首先给 .container 容器设置一个与高度相同的行高,例如这里容器的高度为 300px,所以设置 line-height: 300px,并给容器设置 text-align: center; 水平居中对齐

    在这里插入图片描述

  2. 然后再给 .box 元素设置为行内块(inline-block)元素,并设置 vertical-align: middle; 垂直居中对齐

    在这里插入图片描述

  3. 居中效果有了,但是文字却不见了,因为 .container 容器的 text-alignline-height 默认是会被继承给 .box 元素,这时我们需要通过 line-height: initialtext-align: initial 重置为初始值

    在这里插入图片描述

在线查看效果

✅ 优点: 无需提前知道元素大小,修改元素大小不需要同步修改相关的值

⚠️ 缺点: 需要重置内部元素的文字样式

writing-mode

.container {/* 其它的基础样式... */writing-mode: vertical-lr;text-align: center;
}.inner {width: 100%;display: inline-block;writing-mode: horizontal-tb;
}.box {/* 其它的基础样式... */display: inline-block;text-align: initial;
}
<div class="container"><div class="inner"><div class="box">你好,世界</div></div>
</div>

该方案主要利用 writing-mode 属性,writing-mode 属性可以改变文字的显示方向

  • writing-mode: vertical-lr 让元素文字垂直方向显示
  • writing-mode: horizontal-tb 让元素文字水平方向显示

该方案实现的步骤如下:

  1. 首先将 .container 容器的文字显示方向调整为垂直方向,并设置文字水平居中对齐,用来实现垂直居中

    在这里插入图片描述

  2. 添加一个 .inner 包装元素,设置为行内块(inline-block)元素,并将宽度设置为 100%,并设置文字显示方向为水平方向,此时 .container 容器的 text-align: center; 被继承,变成了水平居中

    在这里插入图片描述

  3. 最后将 .inner 包装元素内部的 .box 元素调整为行内块(inline-block)元素,并重置继承的 text-align 属性的值为初始值

    在这里插入图片描述

在线查看效果

✅ 优点:

  • 兼容性好,适用于 IE 等老版本浏览器
  • 无需提前知道元素大小,修改元素大小不需要同步修改相关的值

⚠️ 缺点:

  • 需要重置内部元素的文字样式
  • 实现和理解起来有点复杂
  • 需要额外的 DOM 元素

table

.container {/* 其它的基础样式... */text-align: center;
}.box {/* 其它的基础样式... */display: inline-block;text-align: initial;
}
<table><tbody><tr><td class="container"><div class="box">你好,世界</div></td></tr></tbody>
</table>

该方案利用了 <table> 标签中 <td> 单元格内容天然是垂直居中的特性,所以只需要再添加一个水平居中就可以实现水平垂直居中。

在线查看效果

✅ 优点:

  • 兼容性好,适用于 IE 等老版本浏览器
  • 无需提前知道元素大小,修改元素大小不需要同步修改相关的值

⚠️ 缺点:

  • 代码冗余,需要额外的 DOM 元素
  • 不符合 <table> 标签正确语义用法
  • 需要重置内部元素的文字水平居中样式

display: table-cell

.container {/* 其它的基础样式... */display: table-cell;text-align: center;vertical-align: middle;
}.box {/* 其它的基础样式... */display: inline-block;text-align: initial;
}

该方案通过将 .container 容器变成 table 单元格显示效果,因为表格单元格的内容默认是垂直居中,在这基础上再加一个 text-align: center; 水平居中即可实现水平垂直居中效果。

在线查看效果

✅ 优点:

  • 兼容性好,适用于 IE 等老版本浏览器
  • 无需提前知道元素大小,修改元素大小不需要同步修改相关的值
  • 相比 <table> 实现没有多余的 DOM 元素

⚠️ 缺点: 需要重置内部元素的文字水平居中样式

Flex

.container {/* 其它的基础样式... */display: flex;justify-content: center;align-items: center;
}

上面这段代码相信大家用的比较多了,我就不详细介绍了。不过 Flex 还有另外一种更加简便的实现方法

.container {/* 其它的基础样式... */display: flex;
}.box {/* 其它的基础样式... */margin: auto;
}

这个方案利用了 Flex 布局中,Flex 子元素的 margin 被设置为 auto,浏览器会将剩余空间平均分配的特性。
在线查看效果

✅ 优点:

  • 无需提前知道元素大小,修改元素大小不需要同步修改相关的值
  • 实现简单,代码量少

⚠️ 缺点: 只适合在现代浏览器中使用。

Grid

.container {/* 其它的基础样式... */display: grid;
}.box {/* 其它的基础样式... */align-self: center;justify-self: center;
}

在线查看效果

✅ 优点:

  • 无需提前知道元素大小,修改元素大小不需要同步修改相关的值
  • 实现简单,代码量少

⚠️ 缺点: 只适合在现代浏览器中使用,更加推荐使用 Flex

总结

元素水平垂直居中的方案主要可以分为以下两类:

固定宽高元素适用的方案

方案兼容性备注
absolute + 负 margin✅ 非常好(IE6+)最老牌的方案,手动计算偏移量
absolute + margin: auto✅ 非常好(IE8+)语义清晰,适合固定尺寸元素
absolute + calc()⚠️ 一般(IE9+)不推荐,既不方便也不通用

宽高不固定元素适用的方案

方案兼容性备注
absolute + transform✅ 较好(IE9+)最常用,推荐优先考虑
line-height✅ 非常好(IE6+)适合单行文字,有继承问题需手动处理
writing-mode✅ 非常好(IE6+)实现和理解起来比较复杂,不推荐
<table> + text-align✅ 非常好(IE6+)结构语义不合理,适合邮件模板等场景
display: table-cell✅ 非常好(IE6+)替代表格结构,语义更合理
flex⚠️ 一般(IE10+)推荐使用,现代项目首选
flex + margin: auto⚠️ 一般(IE10+)更简洁,但仅适合单元素居中
grid⚠️ 较差(IE11 部分支持)简单强大,但需注意兼容性,不如 Flex 普遍
  • 如果项目兼容性要求低,首选 flex + align/justify-centerabsolute + transform 方案
  • 如果需要兼容 IE9 及以下浏览器,首选 absolute + 负 margintable-cell 方案

参考文章

  • CSS实现水平垂直居中的10种方式划重点,这是一道面试必考题,很多面试官都喜欢问这个问题,我就被问过好几次了 要实现上图 - 掘金
  • 实现元素水平+垂直居中的方法(持续更新)1. 父元素:flex flex这个东西简直就是一个神器… 这个时候子元素就 - 掘金
  • 元素水平垂直居中常用方法汇总行内元素 line-height + text-align 行内块状元素 line-heig - 掘金
  • 如何让一个元素水平垂直居中?(代码实例+方案总结) 超详细!!!!在日常的开发中,我们经常会面对这样一个问题:如何实现居 - 掘金

博客地址:https://github.com/wjw020206/blog


http://www.hkcw.cn/article/xgoWpTxQCs.shtml

相关文章

(新)MQ高级-MQ的可靠性

消息到达MQ以后&#xff0c;如果MQ不能及时保存&#xff0c;也会导致消息丢失&#xff0c;所以MQ的可靠性也非常重要。 一、数据持久化 为了提升性能&#xff0c;默认情况下MQ的数据都是在内存存储的临时数据&#xff0c;重启后就会消失。为了保证数据的可靠性&#xff0c;必须…

Microsoft Word使用技巧分享(本科毕业论文版)

小铃铛最近终于完成了毕业答辩后空闲下来了&#xff0c;但是由于学校没有给出准确地参考模板&#xff0c;相信诸位朋友们也在调整排版时感到头疼&#xff0c;接下来小铃铛就自己使用到的一些排版技巧分享给大家。 注&#xff1a;以下某些设置是根据哈尔滨工业大学&#xff08;威…

Linux 基础IO(上)

目录 前言 重谈文件 文件操作 1.打开和关闭 2.对文件打开之后操作 理解文件fd 1.文件fd的分配规则与重定向 2.理解shell中的重定向 3.关于Linux下一切皆文件 关于缓冲区 1.为什么要有缓冲区 2.缓冲区刷新策略的问题 3.缓冲区的位置 前言 本篇到了我们linux中的文件…

单板机8088C语言计划

计划将原来用汇编写的小程序&#xff0c;用C语言重新写一遍 计划2个月能完成 然后再试试&#xff0c;能不能用C写一下固件BootLoad 和一个类似Dos时代的Debug调试器

C++11 语法特性一文详解

文章目录 1. C11 的发展史2. 列表初始化2.1 C98 中使用 {} 的初始化2.2 C11 中使用 {} 进行初始化2.3 std::initializer_list &#xff08;初始化列表&#xff09; 3. 右值引用与移动语义3.1 左值与右值3.1.1 右值分类 3.2 左值引用与右值引用3.2.1 const 左值引用为什么可以绑…

linux基础

参考视频 文章目录 1.网络的三种链接方式2. 目录结构详解3. 远程登陆和远程文件传输4. vi和vim4.1 vi和vim的三种模式4.2 vim快捷键 5. 关机重启和登录注销5.1 关机重启5.2 登录注销 6. 用户管理6.1 添加和删除用户6.2 用户信息6.3 用户组 7. 实用指令7.1 运行级别7.2 找回root…

【MLLM】多模态LLM 2025上半年技术发展(Better、Faster、Stronger)

note 文章目录 note一、新模型趋势任意模态模型推理模型小巧但功能强大的模型专家混合解码器视觉-语言-行动模型 VLA 二、特殊能力视觉语言模型中的目标检测、分割和计数多模态安全模型多模态RAG&#xff1a;检索器和重排器 三、多模态代理四、视频语言模型五、视觉语言模型的新…

python从零开始实现四极场离子轨迹仿真——框架

本篇将主要讲解程序的框架部分。 该程序主要分为三个部分&#xff0c;首先是初始化部分&#xff0c;主要为设置离子质荷比、初始位置、速度。 其次为求解轨迹部分&#xff0c;通过离子位置获取对应位置的电场&#xff0c;并经由空间电荷效应修改电场后&#xff0c;通过数值求解…

YOLO系列中的C3模块解析2025.5.31

YOLO系列中的 C3模块 是YOLOv5引入的核心组件之一&#xff0c;其设计目标是通过轻量化结构和高效特征提取提升模型性能。以下是C3模块的详细解析&#xff1a; 一、C3模块的网络层级结构 C3模块&#xff08;Cross Stage Partial Network with 3 convolutions&#xff09;结合了…

在Cesium中通过geojson和3d tiles分别加载楼宇白膜

一、geojson渲染楼宇白膜&#xff08;不推荐&#xff09; 如果你没有3dtiles文件来加载白膜&#xff0c;只有geojson加载白膜可以通过GeoJsonDataSource来加载白膜&#xff0c;json格式如下。 实现代码如下 <template><div id"cesium_container"></…

CRISPR-Cas系统的小型化研究进展-文献精读137

Progress in the miniaturization of CRISPR-Cas systems CRISPR-Cas系统的小型化研究进展 摘要 CRISPR-Cas基因编辑技术由于其简便性和高效性&#xff0c;已被广泛应用于生物学、医学、农学等领域的基础与应用研究。目前广泛使用的Cas核酸酶均具有较大的分子量&#xff08;通…

【Web API系列】WebTransportSendStream接口深度解析:构建高性能实时数据传输的基石

前言 随着Web应用复杂度的不断提升&#xff0c;传统的HTTP协议在某些场景下&#xff08;如实时游戏、视频流传输&#xff09;逐渐暴露出性能瓶颈。为解决这一问题&#xff0c;W3C提出了WebTransport API&#xff0c;旨在通过基于QUIC协议的低延迟、多路复用传输机制优化实时通…

MySQL中COUNT(*)、COUNT(1)和COUNT(字段名)的深度剖析与实战应用

MySQL中COUNT语句 三种COUNT函数的解析COUNT(*)COUNT(1)COUNT(字段名) 详细性能比较与实测分析性能差异的理论基础实际性能测试案例 实际案例解析案例1&#xff1a;电商平台订单统计案例2&#xff1a;带条件的计数比较案例3&#xff1a;性能优化实例 COUNT函数与索引的关系详解…

VS Code / Cursor 将默认终端设置为 CMD 完整指南

文章目录 &#x1f9ed; 适用范围&#x1f4cc; 背景与问题分析&#x1f6e0; 配置步骤1. 打开设置&#xff08;settings.json&#xff09;2. 添加或更新配置3. 重启终端与编辑器 &#x1f4a1; 补充&#xff1a;支持多个终端配置&#x1f9ef; 常见问题排查✅ 总结 在 Windows…

数据库高可用架构设计:集群、负载均衡与故障转移实践

关键词:数据库高可用,HA架构,数据库集群,负载均衡,故障转移,SQL Server Always On,MySQL InnoDB Cluster,高可用性组,读写分离,灾难恢复 在当今瞬息万变的数字化时代,数据的价值日益凸显,数据库作为承载核心业务数据的基石,其可用性直接决定了业务的连续性与用户…

【C#】一个简单的http服务器项目开发过程详解

这跟安装NoteJs程序运行脚本文件搭建一个简单Http服务器一样&#xff0c;相比起来&#xff0c;它的优点是可以开发的应用是免安装&#xff0c;跨平台的&#xff0c;放在移动盘上便捷的&#xff0c;这里着重讲http服务器实现的过程&#xff0c;以便自主实现特定的功能和服务。 …

谷歌:贝叶斯框架优化LLM推理反思

&#x1f4d6;标题&#xff1a;Beyond Markovian: Reflective Exploration via Bayes-Adaptive RL for LLM Reasoning &#x1f310;来源&#xff1a;arXiv, 2505.20561 &#x1f31f;摘要 通过强化学习 (RL) 训练的大型语言模型 (LLM) 表现出强大的推理能力和紧急反射行为&a…

C# 文件 I/O 操作详解:从基础到高级应用

在软件开发中&#xff0c;文件操作&#xff08;I/O&#xff09;是一项基本且重要的功能。无论是读取配置文件、存储用户数据&#xff0c;还是处理日志文件&#xff0c;C# 都提供了丰富的 API 来高效地进行文件读写操作。本文将全面介绍 C# 中的文件 I/O 操作&#xff0c;涵盖基…

PCB设计教程【强化篇】——USB拓展坞原理图设计

前言 本教程基于B站Expert电子实验室的PCB设计教学的整理&#xff0c;为个人学习记录&#xff0c;旨在帮助PCB设计新手入门。所有内容仅作学习交流使用&#xff0c;无任何商业目的。若涉及侵权&#xff0c;请随时联系&#xff0c;将会立即处理 目录 前言 一、新建工程与元件…

开源版 PyMOL 如何绘制 Galidesivir 分子结构 ?

参阅&#xff1a;开源版PyMol安装保姆级教程 百度网盘下载 提取码&#xff1a;csub pip show pymol 简介: PyMOL是一个Python增强的分子图形工具。它擅长蛋白质、小分子、密度、表面和轨迹的3D可视化。它还包括分子编辑、射线追踪和动画。 先从 www.python.org 下载 python-…