📖
blog
  • README
  • JavaScript
    • 元素的宽高位置信息梳理
    • dom-align 源码浅析
    • Event Loop
    • 函数实参为对象时的陷阱
    • export 与 utils 方法书写规范
    • 手写 Promise 及相关代码理解
    • call,apply,bind 等函数的模拟实现
    • JavaScript继承
    • JavaScript 数据类型与类型判断
    • for..of 和 for..in 的区别
    • 写给自己看的 next 函数
    • JS 可选链与双问号
    • mouseenter 与 mouseover 事件的区别
    • Immutable相关知识
  • CSS
    • 不简单的 z-index
    • 两列布局,三列布局
    • CSS 居中方案整理
    • CSS 像素,设备像素,2倍图梳理
    • iconfont 的使用
  • Node JS
    • 实现简易的 express
  • React 核心知识点整理
    • 高阶组件
    • React 事件处理
    • React Hooks
    • React Context
  • React 状态管理
    • Redux 基础概念
    • Redux 中间件和异步操作
    • Redux Saga
    • Redux 只能有一个 store 对象嘛
  • React 开发实践
    • Ant Design Menu 组件的使用与深入
    • 讲讲吸顶效果与 react sticky
    • 基于 express,搭建 react 的开发环境
    • 通过 antd input 组件分析受控与非受控组件
    • DebounceClick 组件
    • react component Align 组件分析
    • React Portal 之事件冒泡
    • React Transition Group 源码浅析
    • React.cloneElement 父组件向子组件注入 props
    • 一次 Align 组件的问题记录
    • 如何知道子组件的类型
    • React Router 源码简单分析
    • React Redux 源码简单分析
  • Vue.js
    • Vue.js 概览
    • scoped 样式中的 deep
  • TypeScript 语法
    • 基础类型
    • 变量声明
    • 接口
    • 类
    • 函数
    • 泛型
    • 枚举
    • 类型推论
    • 类型兼容性
    • 高级类型
    • Symbol
    • 迭代器和生成器
    • 模块
    • 命名空间
    • JSX
  • 玩转 webpack
    • 第一章: webpack 与构建发展简史
    • 第二章:webpack基础用法
    • 第三章:webpack进阶用法
    • 第四章:编写可维护的 webpack 构建配置
    • 第五章:webpack构建速度和体积优化策略
    • 第六章:通过源代码掌握webpack打包原理
    • 第七章:编写Loader和插件
  • webpack 实践
    • 如何配置 output.library
  • 测试
    • 初识代码测试
    • Jest 中 如何测试 setTimeout
    • Jest Enzyme React 测试实践记录
  • WEB 开发,过往工作沉淀
    • Web安全(DVWA)
    • 内存泄露与事件移除的必要性
    • url to pdf api 与 服务部署踩坑记录
    • 前端调试指南
    • Markdown 转 email
    • github travis ci 自动部署
    • 浏览器缓存知识梳理
    • WEB 系统登录相关知识梳理
    • 将-Axios-请求参数和返回值进行格式化
    • source-map与源码调试
    • HTTPS
    • 使用 rollup 打造自己的 npm 包 (全流程)
    • father-build 是如何工作的
  • 书籍
    • 图解 HTTP 协议
    • 编写可维护的 JavaScript
    • 鸟哥的 Linux 私房菜
    • JavaScript Promise迷你书
  • Linux
    • vimtutor
    • CURL 使用指南
  • Nginx
    • 一次 nginx 分享
  • Git
    • Git Commit Message 须知
    • .gitignore 模板
    • git tag标签
  • 摄影
    • 摄影基础知识
    • 手机摄影从小白到大师
  • 翻译
    • log4js
    • log4js-node
    • 介绍GitLab上的CI/CD
    • 为GitLab Pages创建并调整GitLab CI/CD
    • 关于 rel=noopener
    • AngularJS 团队 Git 提交信息约定
    • JSON Schema
  • Lifehack
    • 20 个 Google 搜索 Tips 来高效使用 Google
    • 37 个高级 Google 搜索 Tips
Powered by GitBook
On this page
  • 前言
  • 1. 水平居中
  • 1.1 行内元素或类行内元素水平居中
  • 1.2 单个块级元素水平居中
  • 1.3 多个块级元素水平居中
  • 2. 垂直居中
  • 2.1 行内或类行内元素垂直居中
  • 2.2 块级元素垂直居中
  • 3. 水平垂直居中
  • 3.1 绝对定位
  • 3.2 flex
  • 3.3 absolute + margin: auto;
  • 3.4 使用 line-height
  • 4. 最后说一说
  • 参考资料

Was this helpful?

  1. CSS

CSS 居中方案整理

前言

认为自己的 CSS 停留在会用的阶段,遇到复杂一些的效果都是各种尝试,没有一些理性的知识做支撑。

这次离职闲暇之余,便想着整理一下常见的 CSS 问题,下次遇到相应的场景,也能够有些参考。

1. 水平居中

1.1 行内元素或类行内元素水平居中

利用 text-align: center 可以实现 块级元素内部 的 内联元素 水平居中

  1. 文本

<p style="text-align: center;background: #f06d06;">
  我要居中
</p>
  1. display 值为 inline, inline-block, inline-table, inline-flex 之一

<p style="text-align: center;background: #f06d06;">
  <div style="display: inline;">
    我要居中
  </div>
</p>

在测试以上代码的时候,发现并不能居中,而且最终渲染的结果是:

<p style="text-align: center;background: #f06d06;">
</p>
<div style="display: inline;">
  我要居中
</div>
<p>
</p>

也就是说, p 标签中不能嵌套 div 标签,否则会造成这种 bug.

于是换用以下代码测试:

<div style="text-align: center;background: #f06d06;">
  // 换成 inline-block, inlint-table, inline-flex 均可
  <div style="display: inline-flex;background: white;">
    我要居中
  </div>
</div>

1.2 单个块级元素水平居中

1.2.1 margin: 0 auto;

通过 margin:0 auto; 使得块级元素水平居中,前提是 设置了居中元素的 width

<div style="background: #f06d06;">
  <div style="width: 200px;margin: 0 auto;background: white;">
    我要居中
  </div>
</div>

1.2.2 width: fit-content

<div style="background: blue; position: relative;">
  <div style="background: red; margin: 0 auto; width: fit-content;">
    我要居中 我要居中 我要居中 我要居中
  </div>
</div>

同上,使用 margin:0 auto; 设置要居中元素为 width: fit-content (相当于明确设置居中元素的宽度), 在 实现水平居中。

缺点是, fit-content 的浏览器兼容略差

1.2.3 绝对定位

通过设置要居中的元素向右移动父元素的 50%, 再向左移动自身元素的 -50%, 即可试下居中。

<div style="background: blue; position: relative;">
  <div style="position: absolute; left: 50%; transform: translateX(-50%); background: red;">
    我要居中 我要居中 我要居中 我要居中
  </div>
</div>

如果已知子元素宽度,比如:

<div style="background: blue; position: relative;">
  <div style="position: absolute; width: 400px; left: 50%; transform: translateX(-50%); background: red;">
    我要居中 我要居中 我要居中 我要居中
  </div>
</div>

此时 tranxlateX(-50%) 还可以换成 margin-left: -200px.

另外,还可以利用 calc, 设置准确的 left 值:

<div style="background: blue; position: relative;">
  <div style="position: absolute; width: 400px; left: calc(50% - 200px); background: red;">
      我要居中 我要居中 我要居中 我要居中
  </div>
</div>

1.3 多个块级元素水平居中

1.3.1 text-align: center 方式

即通过让块级元素变为 inline-block 元素,再让父级 text-align: center 使得元素居中

<div style="text-align: center;">
  <div style="background: red; display: inline-block;">
    a
  </div>
  <div style="background: red; display: inline-block;">
    b
  </div>
  <div style="background: red; display: inline-block;">
    c
  </div>
</div>

1.3.2 flex 布局方式

通过父元素设置为 flex 布局,并设置 justify-content: center 实现居中

<div style="display: flex; justify-content:center;">
  <div style="background: red;">
    a
  </div>
  <div style="background: red;">
    b
  </div>
  <div style="background: red;">
    c
  </div>
</div>

1.3.3 使用 float 实现水平居中

原理是,设置多个元素的共同父元素 float:left, 那么父元素的宽度即为其内容(即子元素)的宽度。子元素设置为 float: left, 保证多个子元素都在同一行。

接着父元素 A 相对父元素的父元素 B left: 50%。然后子元素 C 设置 right: 50% 相对与 A的,其实就类似 A 元素 transform: translateX(-50%), 从而实现居中。

<div style="background: blue;">
  <div style="float: left; position: relative; left: 50%;">
    <div style="background: red;float: left;width: 200px;position: relative; right: 50%;">
      a
    </div>
    <div style="background: red;float: left; width: 200px;position: relative; right: 50%;">
      b
    </div>
    <div style="background: red;float: left; width: 200px;position: relative; right: 50%;">
      c
    </div>
  </div>
</div>

1.3.4 绝对定位实现水平居中

原理同上,通过设置父元素为 position: absolute,使得父元素宽度取决于所包含的内容(即子元素)的宽度

<div style="background: blue;">
  <div style="position: absolute; left: 50%;">
    <div style="background: red;float: left;width: 200px;position: relative; right: 50%;">
      a
    </div>
    <div style="background: red;float: left; width: 200px;position: relative; right: 50%;">
      b
    </div>
    <div style="background: red;float: left; width: 200px;position: relative; right: 50%;">
      c
    </div>
  </div>
</div>

2. 垂直居中

2.1 行内或类行内元素垂直居中

2.1.1 padding-top === padding-bottom

即通过设置 padding-top 和 padding-bottom 相等,使得文字居中 (适用于单行和多行文字)

<div style="background: blue; padding: 20px 0;">
  我要垂直居中
</div>

2.1.2 line-height === height 垂直居中

即设置 line-height 的值与height值一样,但只适用于单行文本,如果有多行,则无效。

<div style=" height: 40px;background: blue; line-height: 40px;">
  我要垂直居中
</div>

2.1.3 table 垂直居中

支持多行文本垂直居中

设置父元素为 display: table,并设定高度。 子元素设为 display: table-cell; vertical-align: middle; 即可

<div style="display: table; height: 100px;">
  <div style="background: blue; display: table-cell;vertical-align: middle;">
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 
 </div>
</div>

同理,我们也可以直接用 table 标签:

默认 tbody 的 vertivcal-align 即为 middle;

<table style="background: red; height: 200px;">
  <tbody>
    <tr>
      <td>
        我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
        我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
        我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
        我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
      </td>
    </tr>
  </tbody>
</table>

2.1.4 flex 布局垂直居中

<div style="background: red; height: 200px; display: flex; flex-direction: column; justify-content: center;">
  <div>
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
  </div>
</div>

2.1.5 幽灵元素实现垂直居中

即某个元素需要垂直居中,那么可以给它加一个兄弟元素(通过父元素为元素的方式),其高度为父元素的 100%.

同时设置两个元素都是 inline-block, 再通过 vertical-align:middle 实现垂直居中。

<style>
  .ghost-center:before {
    content: " ";
    display: inline-block;
    height: 100%;
    width: 1%;
    vertical-align: middle;
  }
</style>

<div style="background: red;height: 200px; position: relative;" class="ghost-center">
    // 注意 p 标签必须限制宽度
  <p style="display: inline-block;background: blue; vertical-align: middle; width: 200px;">
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
  </p>
</div>

2.2 块级元素垂直居中

2.2.1 绝对定位实现垂直居中

元素高度已知

<div style="background: red;height: 200px; position: relative;">
  <p style="background: blue; position: absolute; top: 50%; margin-top: -50px; height: 100px;">
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
  </p>
</div>

元素高度未知

同水平居中一样,高度未知时可以采用 transform: translateY(-50%) 的方式:

<div style="background: red;height: 200px; position: relative;">
  <p style="margin: 0; background: blue; position: absolute; top: 50%; transform: translateY(-50%); height: 100px;">
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
  </p>
</div>

2.2.2 flex 布局

<div style="display: flex; height: 300px; background: red; align-items: center;">
  <div style="background: blue; height: 100px;">
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
    我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
  </div>
</div>

2.2.3 table 布局

同行内元素垂直居中(2.1.3部分内容):

<table>
    <tbody>
    <tr>
      <td>
        <div style="background: green;">
          我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
          我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
          我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
          我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
        </div>
      </td>
    </tr>
  </tbody>
</table>

display: table-cell 也是一样的:

<div style="display: table; height: 300px; background: red;">
  <div style="display: table-cell;vertical-align: middle;">
    <div style="background: blue;">
      我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
      我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
      我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
      我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中 我要垂直居中
    </div>
  </div>
</div>

3. 水平垂直居中

3.1 绝对定位

元素宽高已知

<div style="height: 400px; width: 400px; background: red; position: relative;">
  <div
    style="background: blue; height: 100px; width: 100px; position: absolute; left: 50%; top: 50%; margin-left: -50px; margin-top: -50px;">
    水平垂直居中
  </div>
</div>

absolute + calc 的方式适用于元素宽高已知的情况

同理还有 transform 的方式适用于元素宽高未知的情况

3.2 flex

略,同以上 flex 的方式

display: flex;
justify-content: center;
align-items: center;

3.3 absolute + margin: auto;

即通过绝对定位,同时设置 left,right,top,bottom 均为 0, 此时再设置 margin: auto; 即可实现水平垂直居中。前提是已知元素的宽高

<div style="height: 400px; width: 400px; background: red; position: relative;">
  <div
    style="background: blue; height: 100px; width: 100px; position: absolute; left: 0; right: 0;top:0;bottom:0;margin: auto;">
    水平垂直居中
  </div>
</div>

3.4 使用 line-height

即通过 line-height 垂直居中, text-align: center; 实现水平居中。

在子元素中, line-height: initial; text-align: left; 都是为了消除父元素样式对自己的影响。

<div style="line-height: 200px; width: 200px; background: blue; text-align: center;">
  <div style="background: green; display: inline-block;line-height: initial; text-align: left;">
    我要垂直居中
  </div>
</div>

4. 最后说一说

本文只是对于网上答案的整理,没有原创部分,仅用于自己备忘,在实际工作中遇到相关问题能有资料参考。

该文章从动笔到现在已经两周时间了,忙于搬家,入职新公司等各种事情。现在是深夜 2019-12-09 00:52:00 ,整理完这个知识,接下来新的一周抓紧看 Vue 的文档,把 Entry Task 完成。尽管 Vue 相关技术栈和 TypeScript 都不是熟,一周的时间也觉得有点紧,但也要尽量去完成啊。

另外,对于前端的很多的知识点,希望之后自己都能尽量弄明白,或者是自己的独立思考,或者是整理与理解网上的资料,充实自己也丰富自己的 blog。

参考资料

Previous两列布局,三列布局NextCSS 像素,设备像素,2倍图梳理

Last updated 3 years ago

Was this helpful?

核心参考:

次要参考:

你能实现多少种水平垂直居中的布局(定宽高和不定宽高):

CSS居中完整指南
p标签里面不能嵌套div
六种实现元素水平居中方法
CSS实现水平垂直居中的1010种方式(史上最全)
https://juejin.cn/post/6844903982960214029#heading-18