在 CSS 中要设置元素水平垂直居中是一个很是常见的需求了。但就是这样一个从理论上来看彷佛实现起来极其简单的,在实践中,它每每难住了不少人。浏览器
让元素水平居中相对比较简单:若是它是一个行内元素,就对它的父元素应用 text-align: center
;若是它是一个块级元素,就对它自身应用 margin: auto
。post
然而若是要对一个元素进行垂直居中,那就没有那么容易了,有时候光是想一想就使人头皮发麻了。flex
本文分别从行内元素和块级元素进行说明,将目前比较流行的实现方式进行聚集并解析实现原理,方便你们查阅。这里要说明一点,每一种方式都不是十全十美的,关键要看本身的需求,从而分析出哪一种实现方式是最合适的。ui
行内元素
首先咱们先把基础代码写出来:spa
1 |
<div class="main"> |
1 |
.main { |
class 为 .main
的 div 包裹这一个 class 为 .content
的行内元素 span,咱们的目的就是要让 .content
元素 在 .main
元素中居中。设计
水平居中
text-align
行内元素的水平居中比较简单,咱们直接在 .main
中添加 text-align: center;
便可,此时 .main
变为:code
1 |
.main { |
实现原理: 设置 text-align
的值为 center
,由于该属性规定元素中的文本的水平对齐方式,那么设置为 center
则文本就水平居中了。orm
垂直居中
line-height
行内元素的垂直居中咱们分为 一行
和 多行或者图片等替换元素
来讲明。对象
若是是 一行
,那么咱们可使用 line-height
来实现,此时 .main
元素 css 代码变为:
1 |
.main { |
其实设置了 line-height
就可让文本垂直居中,并不须要同时设置 height
,这里也是一直存在的一个误区。
实现原理: 这种方式实现垂直居中运用的是 CSS 中“行距的上下等分机制”,这也说明了为何该方式只适用于 一行
的文本。
还有一点须要说明是,这种方式实现的垂直居中是“近似”的,并非完美的垂直居中,由于文字字形的垂直中线位置广泛要比真正的“行框盒子”的垂直中线位置低,而因为咱们平时使用的 font-size 比较小,使得这点误差不容易察觉出来,那么感官上也就当作是垂直居中了。
line-height 及 vertical-align
下面再来讲说 多行或者图片等替换元素
的垂直居中效果实现,这里咱们须要同时借助 line-height
和 vertical-align
来实现。
先让文本换行:
1 |
<div class="main"> |
再看修改以后的 css 代码:
1 |
.main { |
实现原理:
- 设置
.content
元素的 display 为 inline-block。做用在于既能重置外部的 line-height 为正常大小,又能保持行内元素特性,从而能够设置 vertical-align 属性,以及产生一个很是关键的“行框盒子”。咱们须要的其实并非这个“行框盒子”,而是每一个“行框盒子”都会附带的一个产物 —— “幽灵空白节点”,即一个宽度为 0,表现如同普通字符的看不见的“节点”。有了这个“幽灵空白节点”,咱们的line-height: 300px;
就有了做用的对象,从而至关于在.content
元素前面撑起了一个高度为 300px 的宽度为 0 的行内元素。 - 由于行内元素默认都是基线对齐的,因此咱们经过对
.content
元素设置vertical-align: middle;
来调整多行文本的垂直位置,从而实现咱们想要的“垂直居中”效果。这种方式也适用于图片等替换元素
的垂直居中效果。固然这里的“垂直居中”也是近似的,这是因为 vertical-align 致使的,具体为何能够深刻了解vertical-align: middle;
。
块级元素
依然先把基础代码写出来:
1 |
<div class="main"> |
1 |
.main { |
class 为 .main
的 div 包裹这一个 class 为 .content
的 块级元素 div,咱们的目的就是要让 .content
元素 在 .main
元素中居中。
position + margin: auto
实现代码以下:
1 |
.main { |
实现原理:
- 设置
.main
元素为相对定位position: relative;
,这样其子元素设置绝对定位时就相对它了。 - 而后设置
.content
元素为绝对定位position: absolute;
并设置它的top
、left
、bottom
、right
都为0,这样该元素的元素的尺寸表现为“格式化宽度和格式化高度”,和<div>
的“正常流宽度”同样,同属于外部尺寸,也就是尺寸自动填充父级元素的可用尺寸,但因为此时咱们设置了.content
元素的宽高,就限制了元素自动填充,这样就多出来150px的空间了。 - 最后咱们设置
.content
元素为margin: auto;
,此时根据 auto 的计算规则,将上下左右剩余空间所有等分了,天然就居中了。
position + margin-left/top
实现代码以下:
1 |
.main { |
实现原理:
- 设置
.main
元素为相对定位position: relative;
,这样其子元素设置绝对定位时就相对它了。 - 而后设置
.content
元素为绝对定位position: absolute;
并设置top: 50%;
、left: 50%;
,这样.content
元素的左上角就位于.main
元素的中心了。 - 最后设置
.content
元素margin-left: -75px;
、margin-top: -75px;
将自身左移及上移宽高的一半,这样.content
元素的中心处于.main
元素的中心处,天然就实现了居中效果。 - 这种方法的缺点就是须要固定
.content
元素的宽高。
position + translate
实现代码以下:
1 |
.main { |
实现原理:
- 设置
.main
元素为相对定位position: relative;
,这样其子元素设置绝对定位时就相对它了。 - 而后设置
.content
元素为绝对定位position: absolute;
并设置top: 50%;
、left: 50%;
,这样.content
元素的左上角就位于.main
元素的中心了。 - 最后设置
.content
元素transform: translate(-50%, -50%);
将自身左移及上移宽高的一半,这样.content
元素的中心处于.main
元素的中心处,天然就实现了居中效果。 - 这种方法的好处就是不须要固定
.content
元素的宽高。
Flexbox
实现代码以下:
1 |
.main { |
实现原理:
- 设置
.main
元素display: flex;
。 - 而后设置
.content
元素为margin: auto;
便可实现居中。 - 这是毋庸置疑的最佳解决方案,咱们不须要设置
.content
元素为绝对定位,margin: auto
天然就能够做用于宽高,并且咱们也不须要设置.content
元素的宽高, 由于Flexbox(伸缩盒)是专门针对这类需求所设计的。 - 缺点就是目前浏览器支持程度相对其它方式会低些。
Flexbox 的另外一个好处在于,它还能够将匿名容器(即没有被标签包裹的文本节点)垂直居中。好比咱们不设置 .main
元素为 display: flex;
,而是设置 .content
元素为 display: flex;
,并借助 Flexbox 规范所引入的 align-items 和 justify-content 属性,咱们可让它内部的文本也实现居中(咱们能够对.main
元素使用相同的属性来使 .content
元素元素居中,但比 margin: auto
方法要更加优雅一些,而且同时起到了回退的做用)。
1 |
.content { |