CSS 中的居中思路

原文:Centering in CSS: A Complete Guide

水平居中 Horizontally

内联元素

包括文本 span 和链接 a 标签之类的内联元素,可以用

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

对于类似inline, inline-block, inline-table, inline-flex的元素都会起作用

块级元素

对于有宽度的块级元素可以设置margin:0 auto来居中

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

多个块级元素

原理类似,可以设置子元素display:inline-block使其变为内联元素,然后通过text-align:center居中,如下

<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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.inline-block-center {
  text-align: center;
}
.inline-block-center div {
  display: inline-block;
  text-align: left;
}
1
2
3
4
5
6
7

flex 也可以起作用,而且更简单

<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
.flex-center {
  display: flex;
  justify-content: center;
}
1
2
3
4

垂直居中 Vertically

内联元素

单行文本

可以设置上下 padding 一样

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

也可以设置 line-heightheight 一样大小

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

多行文本

多行文本用上下 padding 的方式也可以居中,但是如果这还不能满足你的需求,例如在表格单元格里面,可以考虑vertical-align属性

<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
.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

如上,如果不设置vertical-align则默认为baseline,文本会在顶部。设置为middle则居中

浏览器默认 td 标签的vertical-alignmiddle

当然你还是可以用 flexbox 实现

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

使用一个透明的元素撑起容器,通过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
4
5
6
.ghost-center::before {
  content: ' ';
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}
.ghost-center p {
  display: inline-block;
  vertical-align: middle;
}
1
2
3
4
5
6
7
8
9
10
11

块级元素

高度已知

可以使用负边距来实现,如下已知高度100px,可以设置margin-top: -50px来居中

.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
9

高度未知

虽然高度未知,但是还是可以居中,使用 transform 实现

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
1
2
3
4
5
6
7
8

不关心撑开容器的高度

如果不关心撑开容器的高度的高度,可以用table布局,这样在子元素设置display: table-cellvertical-align:midlle可以实现垂直居中,可以参考上面,与<td>标签一样。

<main>
  <div>
    I'm a block-level element with an unknown height, centered vertically within
    my parent.
  </div>
</main>
1
2
3
4
5
6
main {
  background: white;
  height: 300px;
  margin: 20px;
  width: 300px;
  position: relative;
  padding: 20px;
  display: table;
}
main div {
  background: black;
  color: white;
  padding: 20px;
  display: table-cell;
  vertical-align: middle;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

flexbox

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

水平垂直居中

小孩子才做选择,大人全都要。不只是水平,我垂直也要居中。

固定宽高

还是利用的负边距,实现水平垂直居中,当然这里注意父元素的position: relative

.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
13
14
15

宽高未知

使用transform来实现

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
1
2
3
4
5
6
7
8
9

flexbox

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

grid

这是一个比较新的属性,微信还没完全支持。桌面端用的话可以开始了。可以看这里

<span>
  I'm centered!
</span>
1
2
3
body,
html {
  height: 100%;
  display: grid;
}
span {
  /* thing to center */
  margin: auto;
}
1
2
3
4
5
6
7
8
9