CSS居中完全指南

原文地址https://css-tricks.com/centering-css-complete-guide/

CSS居中事件是CSS的难点之一。有人埋怨,为什么一个“居中”要这么难呢?而我认为,这个问题并不是那么复杂,而是因为在不同情况下,总是有多种不同的解决方式,但我们不知道该用哪种。

所以我写了一个决策树,希望能使这个问题更加简单一点。

水平居中

如果需要水平居中的元素是行内元素或是类行内元素(如textlinks

当需要将一个块级元素下的行内元素水平居中时,只需要使用如下代码:

1
2
3
.center-children {
text-align: center;
}

这对设置display属性为inlineinline-blockinline-tableinline-flex等属性的元素有效。

当需要水平居中一个块级元素时

我们可以通过将块级元素的margin-rightmargin-left属性设置为auto来居中它(这时,这个元素必须设定宽度width,否则宽度会为100%而不需要居中),常常我们会这样写:

1
2
3
.center-me {
margin: 0 auto;
}

居中的块级元素或其父元素不管是哪种宽度,这种方法都有效。
值得注意的是,这对浮动元素是无效的。但是,可以看看居中浮动元素的小技巧

当需要居中两个或两个以上的块级元素时

如果你需要在同一行内居中两个或两个以上的块级元素,最好是改变它们的display属性,以下是将display属性设为inline-blockflex的例子:

查看DEMO

如果你想居中从上到下依次排列的几个块级元素,那么当需要水平居中一个块级元素时依然有效。

垂直居中

CSS垂直居中需要一点小技巧。

如果需要垂直居中的元素是行内元素或是类行内元素(如textlinks

如果垂直居中元素只占一行

由于padding-toppadding-bottom相等,inlinetext元素即可表现为垂直居中。

1
2
3
4
.link {
padding-top: 30px;
padding-bottom: 30px;
}

如果由于某些原因不能使用padding属性,在已知该文本不会被包含的前提下,可以将该文本元素的line-heightheight设为相等,即可居中。

1
2
3
4
5
.center-text-trick {
height: 100px;
line-height: 100px;
white-space: nowrap;
}

如果垂直居中元素占多行

padding-toppadding-bottom设为相等也能让包含多行文本的元素居中。但是有时候这种方法也无济于事,那么这个元素或许是类table-cell元素或者就是table-cell元素,这种情况下,就和处理单行文本元素的方式不同了。

查看DEMO

如果table的方式过时了,或许你可以用flexbox,设置flex属性的父元素可以轻松地居中其子元素。

查看DEMO

1
2
3
4
5
6
.flex-center-vertically {
display: flex;
justify-content: center;
flex-direction: column;
height: 400px;
}

记住,之所以这里的父元素包含块都设置了高度height,是因为这和父元素的固定高度真的有很大关系(%、px等)。

如果以上的技巧都已经过时,你可以使用“伪元素”,在包含块中放一个100%高度的伪元素,通过这种方法,文本元素也可在包含块中居中。

查看DEMO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.ghost-center {
position: relative;
}

.ghost-center::before {
content: " "
;

display: inline-block;
height: 100%;
width: 1%;
vertical-align: middle;
}
.ghost-center p {
display: inline-block;
vertical-align: middle;
}

当需要垂直居中一个块级元素时

垂直居中已知高度的块级元素

由于许多原因,常常不能确定网页布局中元素的高度,例如:以为宽度的变化,文本重新排列会改变元素的高度;改变文本的CSS属性会改变元素高度;文本长度的改变也会导致元素高度的改变;像image这种有固定长宽比的元素,调整大小后也会导致高度的改变。

但是,如果你知道高度,你可以使用如下方式垂直居中:

1
2
3
4
5
6
7
8
9
.parent {
position: relative;
}

.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}

垂直居中未知高度的块级元素

这时候,我们仍然可以把元素向上移动其高度的一半来垂直居中它。

1
2
3
4
5
6
7
8
.parent {
position: relative;
}

.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}

也可以使用flexbox

见怪不惊,flexbox会容易得多。

1
2
3
4
5
.parent {
display: flex;
flex-direction: column;
justify-content: center;
}

水平垂直居中

你可以以任何方式组合以上的写法,来达到完美居中元素的目的。但我发现不外乎这三种情况。

如果元素有固定宽度和高度

将元素固定定位,lefttop设为50%,设置负外边距,margin-left设为width的一半,margin-top设为height的一半,兼容大多数浏览器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.parent {
position: relative;
}


.child {
width: 300px;
height: 100px;
padding: 20px;

position: absolute;
top: 50%;
left: 50%;

margin: -70px 0 0 -170px;
}

未知宽高的元素

如果宽高未知,你可以使用transform属性。

1
2
3
4
5
6
7
8
9
.parent {
position: relative;
}

.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

使用flexbox

你需要使用两个居中属性来水平垂直居中元素。

1
2
3
4
5
.parent {
display: flex;
justify-content: center;
align-items: center;
}

总结

完全可以用CSS来达到居中元素的目的。