# 元素居中

# 一、css 实现元素水平居中

margin:0 auto;

给元素设定宽度,而且不能加浮动,即可实现水平居中。左右边距自适应,div 默认宽度最大化,加浮动后,div 宽度最小化。

text-align:center;

一般只能对图片,按钮,文字等行内元素(display 为 inline 或 inline-block)进行水平居中。在 IE6、7 中,它能对任何元素进行水平居中。

DOM 结构

<div class="parent_div">css 实现元素水平居中</div>
1

CSS 样式

.parent_div {
  margin: auto;
  width: 600px;
  height: 300;
  text-align: center;
  border: 3px solid #f00;
}
1
2
3
4
5
6
7

# 二、css 实现元素垂直居中

1、单行文字垂直居中

如果一个容器中只有一行文字,对它实现居中相对比较简单,我们只需要设置它的实际高度 height 和所在行的高度 line-height 相等即可。

.parent_div {
  height: 25px;
  line-height: 25px;
  overflow: hidden;
  border: 3px solid #f00;
}
1
2
3
4
5
6

使用 overflow:hidden 的设置是为了防止内容超出容器或者产生自动换行,这样就达不到垂直居中效果了。

2、行内块级元素

.parent_div::after,
.child_div {
  display: inline-block;
  vertical-align: middle;
}
.parent_div::after {
  content: "";
  height: 100%;
}
1
2
3
4
5
6
7
8
9

3、多行文本固定高度的垂直居中(模拟表格)

CSS 中的 vertical-align 属性只会对拥有 valign 特性的(X)HTML 标签起作用,但是在 CSS 中还有一个 display 属性能够模拟,所以我们可以使用这个属性来让模拟就可以使用 vertical-align 了。注意,display:tabledisplay:table-cell 的使用方法,前者必须设置在父元素上,后者必须设置在子元素上,因此我们要为需要定位的文本再增加一个

元素。

.parent_div {
  display: table;
  height: 300px;
}
.child_div {
  display: table-cell;
  width: 600px;
  vertical-align: middle;
  border: 3px solid #f00;
}
1
2
3
4
5
6
7
8
9
10

Internet Explorer 6 并不能正确地理解 display:table 和 display:table-cell,由此产生以下解决方案。

<div class="parent_div">
  <div class="child_div">
    <div class="child_child_div">css实现元素垂直居中</div>
  </div>
</div>
1
2
3
4
5
.parent_div {
  display: table;
  _position: relative;
  overflow: hidden;
  border: 3px solid #00f;
  width: 600px;
  height: 300px;
}
.parent_div .child_div {
  display: table-cell;
  vertical-align: middle;
  _position: absolute;
  _top: 50%;
}
.child_div .child_child_div {
  _position: relative;
  _top: -50%;
  border: 3px solid #f00;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

4、多行文本不固定高度的垂直居中

.parent_div {
  padding: 25px;
  border: 3px solid #f00;
}
1
2
3
4

使上下的 padding 值相同即可,这种方法的优点就是它可以在任何浏览器上运行,并且代码很简单,只不过这种方法应用的前提就是容器的高度必须是可伸缩的。

5、不固定宽高的垂直居中

<div class="parent_div"><div class="child_div">元素居中</div></div>
1
.parent_div {
  display: table;
  width: 100%;
  border: 3px solid #00f;
}
.parent_div .child_div {
  display: table-cell;
  text-align: center;
  vertical-align: middle;
  border: 3px solid #f00;
}
1
2
3
4
5
6
7
8
9
10
11

# 三、css 实现元素水平垂直居中

1、模拟表格

.parent_div {
  display: table-cell;
  width: 600px;
  height: 500px;
  vertical-align: middle;
  border: 3px solid #f00;
}
.child_div {
  margin: 0 auto;
  width: 200px;
  height: 200px;
  border: 3px solid #00f;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

2、模拟表格,改良版

<div class="parent_div">
  <div class="child_div">
    <div class="child_child_div">css实现元素水平垂直居中</div>
  </div>
</div>
1
2
3
4
5
.parent_div {
  display: table;
  border: 3px solid #f00;
  width: 600px;
  height: 300px;
}
.parent_div .child_div {
  display: table-cell;
  vertical-align: middle;
  border: 3px solid #00f;
  width: 400px;
  height: 200px;
}
.child_div .child_child_div {
  margin: 0 auto;
  width: 50%;
  border: 3px solid #f00;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

总之,这可能是最好的居中实现方法,优点是内容块高度会随着实际内容的高度变化,浏览器兼容性也好。缺点是需要大量额外的标记,需要三层元素让最内层的元素居中。

如果你使用表格布局,那完全不用为各种居中问题而烦恼了,只要用到 td(也可能会用到 th)元素的 align="center" 以及 valign="middle" 这两个属性就可以完美的处理它里面内容的水平和垂直居中问题了,因为表格默认对它里面的内容进行垂直居中。如果想在 css 中控制表格内容的居中,垂直居中可以使用 vertical-align:middle,至于水平居中,貌似 css 中没有相对应的属性,但是在 IE6、7 中,我们可以用 text-align:center 对表格里的元素进行水平居中,IE8+以及谷歌、火狐等浏览器的 text-align:center 只对行内元素起作用,对块状元素无效。在 IE6、7 中,可以通过 css 的 text-algin 来控制表格内容的水平方向的对齐,无论内容是行内元素还是块状元素都有效,但在 IE8+以及 chrome、firefox 等浏览器中,text-align:center 对块状元素无效,只能用表格自有的 align 属性。

3、行内块元素 Inline-Block

基本思想是使用 display: inline-block, vertical-align: middle 和一个伪元素让内容块处于容器中央,下面用 after,也可以用 before。

如果内容块宽度大于容器宽度,比如放了一个很长的文本,但内容块宽度设置最大不能超过容器的 100%减去 0.25em,否则使用伪元素:after 内容块会被挤到容器顶部,使用:before 内容块会向下偏移 100%。

如果你的内容块需要占据尽可能多的水平空间,可以使用 max-width: 99%;(针对较大的容器)或 max-width: calc(100% -0.25em)(取决于支持的浏览器和容器宽度)。

.parent_div {
  text-align: center;
  overflow: auto;
  border: 3px solid #00f;
}
.parent_div:after,
.parent_div .child_div {
  display: inline-block;
  vertical-align: middle;
}
.parent_div:after {
  content: "";
  height: 100%;
  margin-left: -0.25em; /* To offset spacing. May vary by font */
}
.parent_div .child_div {
  max-width: 99%;
  /*preventsissues with long content causes the content block to be pushed to the top */
  border: 3px solid #f00; /* max-width: calc(100% - 0.25em) /* Only for IE9+ */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

这种方法的优劣和单元格 Table-Cell 方式差不多,起初我把这种方式忽略掉了,因为这确实是一种 hack 方法。不过,无论如何,这是很流行的一种用法,浏览器支持的也很好。

优点:

  • 高度可变
  • 内容溢出会将父元素撑开。
  • 支持跨浏览器,也适应于 IE7

缺点:

  • 需要一个容器
  • 水平居中依赖于 margin-left: -0.25em;该尺寸对于不同的字体/字号需要调整
  • 内容块宽度不能超过容器的 100% - 0.25em

4、margin 固定宽高居中

.parent_div {
  margin: auto;
  width: 600px;
  height: 500px;
  border: 3px solid #f00;
}
.child_div {
  margin: 150px 200px;
  width: 200px;
  height: 200px;
  border: 3px solid #00f;
}
1
2
3
4
5
6
7
8
9
10
11
12

这种定位方法纯粹是靠宽高和 margin 拼出来的,不是很灵活。

5、绝对居中 Absolute Centering

.parent_div {
  position: relative;
  margin: auto;
  width: 600px;
  height: 300px;
  border: 3px solid #f00;
}
.child_div {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  width: 200px;
  height: 200px;
  border: 3px solid #00f;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

优点:

  • 支持跨浏览器,包括 IE8-IE10
  • 无需其他特殊标记,CSS 代码量少
  • 支持百分比%属性值和 min-/max-属性
  • 只用一个类即可实现任何内容块居中
  • 不论是否设置 padding 都可居中(在不使用 box-sizing 属性的前提下)
  • 内容块可以被重绘
  • 完美支持图片居中

缺点:

  • 必须声明高度(查看可变高度 Variable Height)
  • 建议设置 overflow:auto 来防止内容越界溢出(查看溢出 Overflow)
  • 在 Windows Phone 设备上不起作用

浏览器兼容性: Chrome,Firefox, Safari, Mobile Safari, IE8-10

6、不确定宽高,绝对定位百分数

.parent_div {
  position: relative;
  margin: auto;
  width: 600px;
  height: 500px;
  border: 3px solid #f00;
}
.child_div {
  position: absolute;
  left: 30%;
  right: 30%;
  top: 15%;
  bottom: 15%;
  border: 3px solid #00f;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

这种不确定宽高的居中,较为灵活。只需要保证 left 和 right 的百分数一样就可以实现水平居中,保证 top 和 bottom 的百分数一样就可以实现垂直居中。

7、负边距 Negative Margins

.parent_div {
  position: relative;
  margin: auto;
  width: 600px;
  height: 300px;
  border: 3px solid #f00;
}
.child_div {
  position: absolute;
  left: 50%;
  top: 50%;
  margin: -100px -100px;
  width: 200px;
  height: 200px;
  border: 3px solid #00f;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Margin-left:-(width + padding)/2,不使用 box-sizing: border-box 时,如果有 padding,要计算 padding ,如果没有 padding,就是-width/2;Margin-top:-(height + padding)/2,不使用 box-sizing: border-box 时,如果有 padding,要计算 padding ,如果没有 padding,就是-height/2

这是唯一在 IE6-IE7 上也表现良好的方法。

优点:

  • 良好的跨浏览器特性,兼容 IE6-IE7
  • 代码量少

缺点:

  • 不能自适应,不支持百分比尺寸和 min-/max-属性设置
  • 内容可能溢出容器
  • 边距大小和 padding 与是否定义 box-sizing: border-box 有关,计算需要根据不同情况

8、弹性盒子 Flexbox

.parent_div {
  display: -webkit-flex;
  display: flex;
  -webkit-align-items: center;
  align-items: center;
  -webkit-justify-content: center;
  justify-content: center;
  margin: auto;
  width: 600px;
  height: 500px;
  border: 3px solid #f00;
}
.child_div {
  width: 200px;
  height: 200px;
  border: 3px solid #00f;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

这是 CSS 布局未来的趋势。Flexbox 是 CSS3 新增属性,设计初衷是为了解决像垂直居中这样的常见布局问题。

优点:

  • 内容块的宽高任意,优雅的溢出
  • 可用于更复杂高级的布局技术中

缺点:

  • IE8/IE9 不支持
  • Body 需要特定的容器和 CSS 样式
  • 运行于现代浏览器上的代码需要浏览器厂商前缀
  • 表现上可能会有一些问题

9、变形 Transform

.parent_div {
  position: relative;
  margin: auto;
  width: 600px;
  height: 500px;
  border: 3px solid #f00;
}
.child_div {
  position: relative;
  top: 50%;
  left: 50%;
  width: 200px;
  height: 200px;
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  border: 3px solid #00f;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

内容块定义 transform: translate(-50%,-50%)必须带上浏览器厂商的前缀。

10、弹层 Transform

.parent_div {
  justify-content: center; /*子元素水平居中*/
  align-items: center; /*子元素垂直居中*/
  display: -webkit-flex;
  border: 3px solid #00f;
}
.parent_div .child_div {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 50%;
  max-width: 640px;
  min-width: 320px;
  height: auto;
  z-index: 2000;
  /*visibility: hidden;*/
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  backface-visibility: hidden;
  -webkit-transform: translateX(-50%) translateY(-50%);
  -moz-transform: translateX(-50%) translateY(-50%);
  -ms-transform: translateX(-50%) translateY(-50%);
  transform: translateX(-50%) translateY(-50%);
  border: 3px solid #f00;
}
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

11、利用 button 做外容器,里边的块元素会自动垂直居中,只需要控制一下水平居中就可以达到效果。

<button class="parent_div"><div class="child_div">水平垂直居中</div></button>
1
.parent_div {
  margin: auto;
  width: 600px;
  height: 500px;
  border: 3px solid #f00;
}
.child_div {
  margin: 0 auto;
  width: 200px;
  height: 200px;
  border: 3px solid #00f;
}
1
2
3
4
5
6
7
8
9
10
11
12

# 四、jquery 实现元素水平垂直居中

$(function() {
  $(window).resize();
});
$(window).resize(function() {
  $(".div").css({
    position: "absolute",
    left: ($(window).width() - $(".div").outerWidth()) / 2,
    top: ($(window).height() - $(".div").outerHeight()) / 2,
  });
});
1
2
3
4
5
6
7
8
9
10

# 五、css 实现浮动元素的居中

设置容器的浮动方式为相对定位,确定容器的宽高,设置层的外边距。