居中是很常见的网页布局,包括水平居中和垂直居中,看起来似乎很简单,但每次到实际用的时候总会发现“咦,怎么不 work”,到底是哪里出了差错,明明这样是可以的啊?

不知道你有没有这种经历,反正我是经常有,所以这里整理一下我们平时常见的居中场景以及分别实现水平居中和垂直居中的方法。
常见的居中场景
- 文本居中
- div 中的 div 居中
- button 居中
- 图片居中
其中垂直居中还包括元素高度固定和不定两种。
水平居中
水平居中比较简单,主要实现方法如下。
对于行内元素可以直接设置父元素为
text-align: center;即可,对于文本居中、button 居中、图片居中均适用。对于块级元素或者是
inline-block的元素可以借助子元素的margin值来实现,设置子元素为margin: 0 auto;即可。
如果内层元素有多个的话想要整体居中怎么做呢,做法大致相同。
这种情况下内层元素一般有设置宽度,因为如果是块级元素的话默认占满整行,这样是谈不上居中的。
将内层的元素设置为 display: inline-block; 使其居于一行,然后外层元素设置 text-align: center;,如下图:

- 若子元素包含
float:left属性,为了让子元素水平居中,则可让父元素宽度设置为fit-content,并且配合margin, 作如下设置:
.parent{
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
margin: 0 auto;
}
fit-content 是 CSS3 中给 width 属性新加的一个属性值,它配合 margin 可以轻松实现水平居中, 目前只支持 Chrome 和 Firefox 浏览器
- 使用绝对定位方式,以及负值的
margin-left, 子元素设置如下:
.son{
position: absolute;
width: 固定;
left: 50%;
margin-left: -0.5宽度;
}
- 使用绝对定位方式, 以及
left:0;right:0;margin:0 auto;子元素设置如下:
.son{
position: absolute;
width: 固定;
left: 0;
right: 0;
margin: 0 auto;
}
这里解释一下为什么 left 和 right 要设置为 0
定位元素的宽度和水平放置满足一个等式。
left+ margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-righ + right = 包含块的宽度
默认情况下,这四个值都是 auto,会相对于其静态位置放置,所谓静态位置是指元素在浮动之前所占据的位置。在从左往右读的语言中,left 会被设置为 auto,则值为静态位置左边界距离包含块左边界的像素值,同理 right 会设置为静态位置右边界距离包含块右边界的像素值,此时刚好
left+ border-left-width + padding-left + width + padding-right + border-right-width + right = 包含块的宽度
因此左右 margin 自动变为 0,这时我们设置 margin: 0 auto; 不会有任何左右,所以需要将 left 和 right 设置为 0 使得 margin: 0 auto; 生效,从而实现居中。
- 使用 CSS3 中新增的
transform属性, 子元素设置如下:
(这种类似于上面提到的利用绝对定位以及负值的margin-left,同样是先根据绝对定位偏移 50%,然后往回移动自身宽度的一半达到居中)
.son{
position: absolute;
left: 50%;
transform: translateX(-50%);
}
- 使用
flex
在 Flex 出现之后,居中的实现变得简单了很多,它几乎可以解决所有的居中问题,目前主流浏览器均已支持 Flex,在某些低版本的 IE 尚不支持。
父元素设置如下:
.parent {
display: flex;
justify-content: center;
}

垂直居中
垂直居中比较狡猾,经常会出现意想不到的问题。
1. 元素高度固定
如果是单行文本,可以设置
line-height和height同高使用相对定位,父元素设置
position: relative;,子元素设置如下:
.son{
position:absolute;
top:50%;
height:固定;
margin-top:-0.5高度;
}
or
.son{
position:absolute;
height:固定;
top:0;
bottom:0;
margin:auto 0;
}
2. 元素高度不固定
- 使用
vertical-align: middle;
使用 vertical-align: middle; 来达到居中也是很常见的一种做法,但是在某些情况下,我们会发现加了并没有起作用,这是因为 vertical-align: middle; 只有在某些情况下才会生效。
vertical-align: middle; 起作用的前提是元素为 inline 水平元素或者 display: table-cell; 元素,包括 span, img, span, input, button, td 以及通过 display 属性使之显示为 inline 或者 table-cell 的元素。这意味着,默认情况下,vertical-align: middle; 对 div 和 p 元素等无效。
此外,vertical-align: middle; 只有当父元素设置了 line-height 时才会起作用。(line-height 和 height 同高)
vertical-align不可继承,必须对子元素单独设置
- 使用
transform,利用父元素相对定位(position:relative),子元素设置如下:
.son {
transform: translateY(-50%);
position: absolute;
top: 50%;
}
- 使用 Flex 布局,父元素设置如下:
.parent {
display: flex;
align-items: center;
}
总结
水平居中的方法:
- 文本居中使用
text-align: center; - 利用元素的
margin - 元素宽度设置为
fit-content(IE 不支持) - 使用绝对定位和元素的负
margin或者left, right, top, bottom - 使用绝对定位和
transform - 使用 Flex
垂直居中的方式:
- 文本居中使用
line-height - 使用相对定位和元素的负
margin或者left, right, top, bottom - 使用
vertical-align(有一定使用环境和前提) - 使用绝对定位和
transform - 使用 Flex