水平居中和垂直居中在网页布局中有着广泛的应用,本文总结了怎么实现水平或者垂直居中的几种方法,根据不同的情况,选用合适的方法,就可以达到想要的效果。
# 水平居中
# 是否是内联或者是类内联元素(比如是文本或者是链接)
在块级元素的父级内可以水平居中内联元素,只需要
.center-children {
  text-align: center;
}
 1
2
3
2
3
对inline, inline-block, inline-table, inline-flex等都有效
# 是否是块级元素
对块级元素设置一定的宽度,然后自动左右外边距就可以实现
.center-me {
  width: 100px;
  margin: 0 auto;
}
 1
2
3
4
2
3
4
# 是否超过一个块级元素
假如需要两个或者是更多的块级元素需要在一行中居中,改变他们的 display 类型可以达到这个目的,下面是分别设置 display 为 inline-block 和 flexbox 的例子
<main class="inline-block-center">
  <div>
    I'm an element that is block-like with my siblings and we're centered in a row.
  </div>
  <div>
    I'm an element that is block-like with my siblings and we're centered in a row. I have more content in me than my siblings do.
  </div>
  <div>
    I'm an element that is block-like with my siblings and we're centered in a row.
  </div>
</main>
<main class="flex-center">
  <div>
    I'm an element that is block-like with my siblings and we're centered in a row.
  </div>
  <div>
    I'm an element that is block-like with my siblings and we're centered in a row. I have more content in me than my siblings do.
  </div>
  <div>
    I'm an element that is block-like with my siblings and we're centered in a row.
  </div>
</main>
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
body {
  background: #ccc;
  font-size: 80%;
}
main {
  background: white;
  margin: 20px 0;
  padding: 10px;
}
main div {
  background: black;
  color: white;
  padding: 15px;
  max-width: 125px;
  margin: 5px;
}
.inline-block-center {
  text-align: center;
}
.inline-block-center div {
  display: inline-block;
  text-align: left;
}
.flex-center {
  display: flex;
  justify-content: center;
}
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
效果

当然如果这些块级元素只是堆叠在一起,设置外边距auto的方式仍然适合
# 垂直居中
# 是否是内联或者是类内联元素(比如是文本或者是链接)
# 是否是单行
设置上下内边距相等会使得文本垂直居中,如果因为某些原因无法设置内边距,比如这行文字没有被包裹着,那么有个技巧是设置行高line-height等于高也是可以居中文本
.center-text-trick {
  height: 100px;
  line-height: 100px;
}
 1
2
3
4
2
3
4
# 是否是多行
同样可以设置等值的上下内边距来实现垂直居中的效果,如果没效果的话,有可能文本元素是一个table cell, 这是可以用vertical-align是处理这种情况
<table>
  <tr>
    <td>
      I'm vertically centered multiple lines of text in a real table cell.
    </td>
  </tr>
</table>
<div class="center-table">
  <p>I'm vertically centered multiple lines of text in a CSS-created table layout.</p>
</div>
 1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
body {
  background: #ccc;
  font-size: 80%;
}
table {
  background: white;
  width: 240px;
  border-collapse: separate;
  margin: 20px;
  height: 250px;
}
table td {
  background: black;
  color: white;
  padding: 20px;
  border: 10px solid white;
  /* default is vertical-align: middle; */
}
.center-table {
  display: table;
  height: 250px;
  background: white;
  width: 240px;
  margin: 20px;
}
.center-table p {
  display: table-cell;
  margin: 0;
  background: black;
  color: white;
  padding: 20px;
  border: 10px solid white;
  vertical-align: middle;
}
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
效果

如果用table的方式都不起作用,浏览器支持的情况下可以使用[flexbox](http://caniuse.com/#search=flexbox flexbox_support),查看flexbox语法
<div class="flex-center">
  <p>I'm vertically centered multiple lines of text in a flexbox container.</p>
</div>
 1
2
3
2
3
body {
  background: #ccc;
  font-size: 80%;
}
div {
  background: white;
  width: 240px;
  margin: 20px;
}
.flex-center {
  background: black;
  color: white;
  border: 10px solid white;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 200px;
  resize: vertical;
  overflow: auto;
}
.flex-center p {
  margin: 0;
  padding: 20px;
}
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
效果

这种情况下,父级 container 必须有一个固定的高度( px,  % 等),如果这些方式都失效,可以尝试使用"ghost element"的方法,在 container 内部放一个占满高度的伪元素,然后 vertical-align: middle; 的方式垂直居中
<div class="ghost-center">
  <p>I'm vertically centered multiple lines of text in a container. Centered with a ghost pseudo element</p>
</div>
 1
2
3
2
3
body {
  background: #ccc;
  font-size: 80%;
}
div {
  background: white;
  width: 240px;
  height: 200px;
  margin: 20px;
  color: white;
  resize: vertical;
  overflow: auto;
  padding: 20px;
}
.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;
  width: 190px;
  margin: 0;
  padding: 20px;
  background: black;
}
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
效果

# 是否是块级元素
# 如果知道元素的高度
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px;
}
 1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 元素的高未知
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
 1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
可以使用flexbox?
.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
 1
2
3
4
5
2
3
4
5
# 水平和垂直居中
# 有固定的宽和高
.parent {
  position: relative;
}
.child {
  width: 300px;
  height: 100px;
  padding: 20px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -70px 0 0 -170px;
}
 1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 没有固定的宽和高
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
 1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 可以使用flexbox
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}
 1
2
3
4
5
2
3
4
5