CSS制作水平垂直居中对齐

作为前端攻城师,在制作Web页面时都有碰到CSS制作水平垂直居中,我想大家都有研究过或者写过,特别的其中的垂直居中,更是让人烦恼。这段时间,我收集了几种不同的方式制作垂直居中方法,但每种方法各有千秋呀,要正确的选择也是一件不容易的事情。我会将这几种方法一一介绍给大家,以供大家参考。或许对于我这样的初学者有一定的帮助。

用CSS来实现元素的垂直居中效果是件苦差事,虽然说实现方法有多种,但有很多方式在某些浏览器下可能无法正常的工作。接下来我们就一起来看看这些不同方法实现垂直居中的各自优点和其不足之处。

方法一:

这种方法用来实现单行垂直居中是相当的简单的,你只要保证元素内容是单行,并且其高度是固定不变的,你只要将其“line-height”设置成和“height”值一样就Ok了。不过这种方法局限性太大,只有单行文本的元素才适用,所以在多行元素中是不能使用这种方法的。

1
2
3
4
5
6
<div class="vertical">content</div>
.vertical {
height: 100px;
line-height: 100px;/*值等于元素高度的值*/
}

优点:

适合在所有浏览器,没有足够空间时,内容不会被切掉

缺点:

仅适合应用在文本和图片上,并且这种方法,当你文本不是单行时,效果极差,差到让你感到恶心。
这种方法对运用在小元素上是非常有用的,比如说让一个button、图片或者单行文本字段。

方法二:

这种方法将在需要给容器设置绝对定位(position:absolute),并且定位高度(top:50%)和margin-top为高度的一半(margin-top:-height/2)。这就意味着使用这种方法来实现垂直居中的效果,那么元素必须要有一个固定的高度。这样一来,你给元素设置了固定高度,如果你又给他设置了“overflow:auto”,那么当元素内容超过容器后,这样元素的就会出现滚动,而不会自适应内容的高度。

1
2
3
4
5
6
7
8
<div class="vertical">content</div>
.vertical {
height: 100px;/*元素的高度*/
position: absolute;
top: 50%;/*元素的顶部边界离父元素的的位置是父元素高度的一半*/
margin-top: -50px;/*设置元素顶边负边距,大小为元素高度的一半*/
}

优点:

能在各浏览器下工作,结构简单明了,不需增加额外的标签

缺点:

由于固定死元素的高度,致使没有足哆的空间,当内容超过容器的大小时,要么会消息,要么会出现滚动条(如果元素在body内,当用户缩小浏览器窗口时,body的滚动条将不会出现)。

这种方法主要是针对多行元素来进行元素的垂直居中,而并非是此元素的内容垂直居中,这一点先要理解并分开清楚。另外此方法是通过绝对定位来实现的,那么用这种方法实现元素的垂直居中需要注意以下几点:其一元素定位关系到一个相对定位参考,所以要保证元素是相对于哪个为参考坐标;另外需要设置给元素明确定一个高度值并且给元素设置一个负值的margin-top,而且值为元素高度的一半。这里我建议大家给元素定一个宽度值,因为元素进行绝对定位后脱离文档流,其宽度是根据元素内容所占宽度来计算的,为这能让其视觉效果更好,最好给元素定义一个宽度值。

根据这种方法,我们稍作修改就能使元素不单是垂直居中,而且还可以水平居中,如:

1
2
3
4
5
6
7
8
9
10
<div id="wrap">test</div>
#wrap {
width: 200px;/*元素的宽度*/
height:200px;/*元素的高度*/
position: absolute;
left: 50%;/*配合margin-left的负值实现水平居中*/
margin-left: -100px;/*值的大小等于元素宽度的一半*/
top:50%;/*配合margin-top的负值实现垂直居中*/
margin-top: -100px;/*值的大小等于元素高度的一半*/
}

这种方法可以实现元素的水平垂直居中,常用于页面在最中间的布局,使用这种方法一定要把握住:水平垂直居中的元素要有明确的大小(换句话说就是要有确切的宽和高度值);给元素进行绝对定位,并设置left,top值为“50%”(此处最好使用 对定位,如果只是单单水平居中,此处可以换成相对定位);最后设置margin-top和margin-left的负值,而且其值分别为元素高度和宽度的一半。

方法三:

方法三是使用的的div模拟表格效果,也就是说将多个

的“display”属性设置为禾“table”和“table-cell”,并设置他们的“vertical-align”的属性值为“middle”。有关于“display:table”更多的介绍可以点击这里或者去阅读Quirksmode的《The display declaration》一文。
1
2
3
4
5
6
7
8
9
10
11
12
<div id="container">
<div id="content">content</div>
</div>
#container {
height: 300px;
display: table;/*让元素以表格形式渲染*/
}
#content {
display:table-cell;/*让元素以表格的单元素格形式渲染*/
vertical-align: middle;/*使用元素的垂直对齐*/
}

优点:

这种方法不会像前面的两种方法一样,有高度的限制,此方法可以要据元素内容动态的改变高度,从而也就没有空间的限制,元素的内容不会因为没足够的空间而被切断或者出现难看的滚动条。

缺点:

不足之处呢?这种方法只适合现代浏览器,在IE6-7下无法正常运行;而且较前两者而言,结构也更复杂。

这种方法在现代浏览器下是非常方便。但是在IE6-7中是不被支持的,因为display:table在IE6-7中不被支持,那么为了解决这种方法在IE6-7的兼容,需要额外增加一个div,并使用hack,下面我们一起来看看其解决办法。

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
<div class="table">
<div class="tableCell">
<div class="content">content</div>
</div>
</div>
.table {
height: 300px;/*高度值不能少*/
width: 300px;/*宽度值不能少*/
display: table;
position: relative;
float:left;
}
.tableCell {
display: table-cell;
vertical-align: middle;
text-align: center;
padding: 10px;
*position: absolute;
*top: 50%;
*left: 50%;
}
.content {
*position:relative;
*top: -50%;
*left: -50%;
}

方法四:

这种方法有点新意,用这种方法你需要在居中元素前面放一个空的

(块元素就可以),然后设置这个
的高度为50%,margin-bottom为元素高度的一半,而且居中元素需要清除浮动。需要注意的是,使用这种方法,如果你的居中元素是放在body中的话,你需要给html,body设置一个“height:100%”的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<div id="floater"><!--This block have empty content --></div>
<div id="content">Content section</div>
</body>
html,body {height: 100%;}
#floater{
float:left;
height:50%;/*相对于父元素高度的50%*/
margin-bottom: -120px;/*值大小为居中元素高度的一半(240px/2)*/
}
#content {
clear:both;/*清除浮动*/
height: 240px;
position: relative;
}

优点:

这种方法能兼容所有浏览器,在没有足哆空间下,内容不会被切掉

缺点:

元素高度被固定死,无法达到内容自适应高度,如果居中元素加上overflow属性,要么元素出现滚动条,要么元素被切掉;另外就是一个不算缺点的缺点,那就是加了一个空标签。

方法五:

这种方法和方法三一样使用display:table-cell来实现,不过方法五不同之处是这个方法我们需要一个线盒型,用来实现IE下的效果,需要增加一上行内标签比如说“span”(此处最好使用行内标签,千万不要使用块标签,因为使用块标签会没有效果),并把这个线盒型高度设置为100%,其实现原理大家可以去阅读张鑫旭-鑫空间-鑫生活的《大小不固定的图片、多行文字的水平垂直居中》。

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
<p class="table">
<span class="tableCell">Centering multiple lines <br>in a block container.</span>
<!--[if lte IE 7]><b></b><![endif]-->
</p>
<style type="text/css">
.table {
border: 1px solid orange;
display: table;
height: 200px;
width: 200px;
text-align: center;
}
.tableCell {
display: table-cell;
vertical-align: middle;
}
</style>
<!--[if lte ie 7]>
<style type="text/css">
.tableCell {
display: inline-block;
}
b {
display: inline-block;
height: 100%;
vertical-align: middle;
width: 1px;
}
</style>
<![endif]-->

优点:

这种方法的优点和方法三是一样的,不会有高度的限制。

缺点:

不好的地方就是这种方法为了让IE运行正常,需要额外增加一些标签,另外就是线盒型的标签种类有限制。不过用起来还是蛮方便的。

方法六:

这种方法是采用的display:inline-block,然后借助另一个元素的高度来实现居中

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
38
39
40
41
<div id="parent">
<div id="vertically_center">
<p>I am vertically centered!</p>
</div>
<div id="extra"><!-- ie comment --></div>
</div>
<style type="text/css">
html,
body{
height: 100%;
}
#parent {
height: 500px;/*定义高度,让线盒型div#extra有一个参照物,可以是固定值,也可以是百分比*/
border: 1px solid red;
}
#vertically_center,
#extra {
display: inline-block;/*把元素转为行内块显示*/
vertical-align: middle;/*垂直居中*/
}
#extra {
height: 100%; /*设置线盒型为父元素的100%高度*/
}
</style>
<!--[if lt IE 8]>
<style type="text/css">
/*IE6-7不支持display:inline-block,所以在ie6-7另外写一个hack,用来支持ie6-7*/
#vertically_center,
#extra {
display: inline;
zoom: 1;
}
#extra {
width: 1px;
}
</style>
<![endif]-->

优点:

可以自适应高度,简单易懂

缺点:

需要给元素的父元素设置一个高度,这个高度可以是一个固定值或者百分值高度,另外需要增加一个额外的标签,当作线盒型,如div#extra,并且需要设置其高度为100%。另外就是ie6-7不支持display:inline-block,需要给他们另外写一个样式。

这是一个很有意思的方法,但你要懂得如何使用display。有关于这种方法的操作,大家可以去看一看Jonathan Potter写的《CSS, Vertical Centering》。

方法七:

这个方法是针对多行内容居中,而且容器高度是可变的,方法很简单,就是给出上下一样的padding值

1
2
3
4
5
<div class="columns">
<div class="item">test</div>
</div>
.item {padding-top:30px;padding-bottom:30px;}

优点:

在所有浏览器下能正常工作,支持所有元素,简单易懂,结构清晰

缺点:

使用这种方法不能给容器固定高度,如果固定高度将无法达到效果。

方法八:

正如前面所述,如果元素固定高度后要实现垂直居中,用CSS实现很方便,但对于自适应高度的就比较棘手了。那么第七种方法,要给大家介绍的是使用jQuery的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="container">
<p>Centered In The Middle Of The Page With jQuery</p>
</div>
.container{
background-color:#338BC7;
width:270px;
height:150px;
}
$(document).ready(function(){
$(window).resize(function(){
$('.container').css({
position:'absolute',
left: ($(window).width() - $('.container').outerWidth())/2,
top: ($(window).height() - $('.container').outerHeight())/2
});
});
// 最初运行函数
$(window).resize();
});

优点:

这种方法,结构简单,易懂,不需要固定元素的大小。兼容各浏览器。

缺点:

需要调用jQuery,如果不支持js或者用户禁掉了js,那么将无法正常运行,那就是杯具了。

上面这种方法对实现页面居中布局很方便,下面我根据上面的思路和方法二写了一个实现元素水平垂直居中的小插件

  • jQuery Plugin

    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
    (function($){
    $.fn.vhAlign = function(){
    return this.each(function(i){
    //获取元素的内容高度
    var h = Math.ceil($(this).height());
    //outerHeight=padding+border+height
    var oh = Math.ceil($(this).outerHeight());
    //取得margin-top值
    var mt = Math.ceil(oh / 2);
    //取得元素宽度
    var w = Math.ceil($(this).width());
    //outerWidth=padding+border+width
    var ow = Math.ceil($(this).outerWidth());
    //取得margin-left
    var ml = Math.ceil(ow / 2);
    //实现元素居中效果
    $(this).css({
    "margin-top": "-" + mt + "px",
    "top": "50%",
    "margin-left": "-" + ml + "px",
    "left": "50%",
    "width":w,
    "height":h,
    "position": "absolute"
    });
    });
    };
    })(jQuery);
  • Html Markup

    1
    2
    3
    <div class="wrap">
    <p>test jquery</p>
    </div>

接下来需要调用刚才写好的jQuery插件

1
<script type="text/javascript" src="vhAlign.js"></script>

最后需要在div.wrap调用这个function

1
2
3
4
5
<script type="text/javascript">
$(document).ready(function(){
$(".wrap").vhAlign();
});
</script>

这里有一点需要特别注意,如果元素不是相对于body居中,那么需要在其父元素中进行相对定位。

上面我们一起见证了八种不同方法实现元素的垂直居中效果,下面我们在简单的看一下如何实现元素的水平居中(其实上面有一些效果也实现了水平居中,你可以慢慢回想一下)。

方法一:

这种方法主要使用margin: auto配合元素的width来实现水平居中的效果

1
2
3
4
5
6
7
//Html Markup
<div class="horizontal">content</div>
//CSS Code:
.horizontal {
width: 200px;
margin: 0 auto;
}

使用上面方法实现元素水平居中一定要让元素满足两个条件:其一,元素需要有一个固定宽度值;其二元素的margin-left和margin-right都必须设置为auto,这两个条件少了任何一个都无法让元素达到水平居中的效果。此方法使用水平居中,支持所有浏览器运行,因此他也常用来实现Web页面水平居中的布局效果,如果用在布局,需要注意IE下的效果,换句话说,如果你的Web页面没有明确声明”!DOCTYPE”,那么在IE也会以怪异模式解析你的Web页面,此时上面这种办法将无法让你的页面实现水平居中,但你可以使用下面这种方法解决这个bug。

1
2
3
4
5
6
7
8
9
<div class="container"> 页面内容。... </div>
body {
text-align: center;/*实现IE在怪异模式下页面水平居中*/
}
.container {
text-align: left;/*让文本恢复到左对齐*/
width: 960px;/*设置页面总宽度*/
margin: 0 auto;/*使页面水平居中对齐*/
}

方法二:

实现固定宽度的水平居中,我们还可以使用绝对定位配合负的margin来实现,具体代码如下:

1
2
3
4
5
6
7
<div class="horizontal">content</div>
.horizontal {
width: 960px;
position: absolute;
left: 50%;
margin-left: -480px;/*此值等于“-width/2”*/
}

这种方法有几点需要注意:其一要有一个固定宽度,其二对要居中的元素进行绝对定位,并且“left: 50%”;其三对此元素设置一个负的“margin-left”并且值等于宽度的一半,另外如果元素不是相对于浏览器的话,还需要在其父元素上设置一个相对定位“position: relative”。

方法三:

这种方法主要是针对单行文本居中或者前面介绍的table格式居,主要运用的是text-align:center让元素水平居中

1
.testH{text-align:center;}

上面主要是和大家一起探讨和学习了多种方法让元素实现垂直居中,大家可以在这几种方法上稍做改变就能实现其水平居中,这样就达到了元素水平垂直居中的效果。实现方法很多,而且他们也各有千秋,可以说他们各有各的好,各有各的坏,具体怎么让他们更适合你的实际应用,你可以仔细对比一下,我比较喜欢方法四,简单,兼容性强,只是需要增加一个额外的标签。说了这么多,希望能给需要的朋友有所帮助。

水平居中和垂直居中另类解决方案

熟悉水平居中和垂直居中的方法, 不为别的, 就为用的时候能够信手拈来. 下面直接步入正题.

水平居中

1) 若是行内元素, 给其父元素设置 text-align:center,即可实现行内元素水平居中.
2) 若是块级元素, 该元素设置 margin:0 auto即可.
3) 若子元素包含 float:left 属性, 为了让子元素水平居中, 则可让父元素宽度设置为fit-content,并且配合margin, 作如下设置:

1
2
3
4
5
6
.parent{
width: -moz-fit-content;
width: -webkit-fit-content;
width:fit-content;
margin:0 auto;
}

fit-content是CSS3中给width属性新加的一个属性值,它配合margin可以轻松实现水平居中, 目前只支持Chrome 和 Firefox浏览器.

4) 使用flex布局, 可以轻松的实现水平居中, 子元素设置如下:

1
2
3
4
.son{
display: flex;
justify-content: center;
}

5) 使用css3 盒模型, 父元素display: box;box-pack: center;如下设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.parent {
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-pack: center;
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-pack: center;
display: -o-box;
-o-box-orient: horizontal;
-o-box-pack: center;
display: -ms-box;
-ms-box-orient: horizontal;
-ms-box-pack: center;
display: box;
box-orient: horizontal;
box-pack: center;
}

6) 使用CSS3中新增的transform属性, 子元素设置如下:

1
2
3
4
5
.son{
position:absolute;
left:50%;
transform:translate(-50%,0);
}

7) 使用绝对定位方式, 以及负值的margin-left, 子元素设置如下:

1
2
3
4
5
6
.son{
position:absolute;
width:固定;
left:50%;
margin-left:-0.5宽度;
}

8) 使用绝对定位方式, 以及left:0;right:0;margin:0 auto; 子元素设置如下:

1
2
3
4
5
6
7
.son{
position:absolute;
width:固定;
left:0;
right:0;
margin:0 auto;
}

垂直居中

单行文本

1) 若元素是单行文本, 则可设置 line-height 等于父元素高度

行内块级元素

2) 若元素是行内块级元素, 基本思想是使用display: inline-block, vertical-align: middle和一个伪元素让内容块处于容器中央.

1
2
3
4
5
6
7
8
.parent::after, .son{
display:inline-block;
vertical-align:middle;
}
.parent::after{
content:'';
height:100%;
}

这是一种很流行的方法, 也适应IE7.

元素高度不定

3) 可用vertical-align 属性, 而vertical-align只有在父层为 td 或者 th 时, 才会生效, 对于其他块级元素, 例如 divp 等, 默认情况是不支持的. 为了使用vertical-align, 我们需要设置父元素display:table, 子元素 display:table-cell;vertical-align:middle;

优点

元素高度可以动态改变, 不需再CSS中定义, 如果父元素没有足够空间时, 该元素内容也不会被截断.

缺点

IE6~7, 甚至IE8 beta中无效.

4) 可用 Flex, 这是CSS布局未来的趋势. Flexbox是CSS3新增属性, 设计初衷是为了解决像垂直居中这样的常见布局问题. 相关的文章如《Centering Elements with Flexbox》

父元素做如下设置即可保证子元素垂直居中:

1
2
3
4
.parent {
display: flex;
align-items: center;
}
优点
  • 内容块的宽高任意, 优雅的溢出.
  • 可用于更复杂高级的布局技术中.
缺点
  • IE8/IE9不支持
  • 需要浏览器厂商前缀
  • 渲染上可能会有一些问题

5) 使用CSS3盒模型

.parent {
      display: box;
      box-orient: vertical;
      box-pack: center;
}    
优点
  • 实现简单, 扩展性强
缺点
  • 兼容性差, 不支持IE

6) 可用 transform , 设置父元素相对定位(position:relative), 子元素如下css样式:

1
2
3
4
5
6
7
.son{
position:absolute;
top:50%;
-webkit-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
}
优点
  • 代码量少
缺点
  • IE8不支持, 属性需要追加浏览器厂商前缀, 可能干扰其他 transform 效果, 某些情形下会出现文本或元素边界渲染模糊的现象.
    元素高度固定

元素高度固定

7) 设置父元素相对定位(position:relative), 子元素如下css样式:

1
2
3
4
5
6
.son{
position:absolute;
top:50%;
height:固定;
margin-top:-0.5高度;
}
优点
  • 适用于所有浏览器.
缺点
  • 父元素空间不够时, 子元素可能不可见(当浏览器窗口缩小时,滚动条不出现时).如果子元素设置了overflow:auto, 则高度不够时, 会出现滚动条.

8) 设置父元素相对定位(position:relative), 子元素如下css样式:

1
2
3
4
5
6
7
.son{
position:absolute;
height:固定;
top:0;
bottom:0;
margin:auto 0;
}
优点
  • 简单
缺点
  • 没有足够空间时, 子元素会被截断, 但不会有滚动条.

总结

水平居中较为简单, 共提供了8种方法, 一般情况下 text-align:center,marin:0 auto; 足矣

  • ① text-align:center;
  • ② margin:0 auto;
  • ③ width:fit-content;
  • ④ flex
  • ⑤ 盒模型
  • ⑥ transform 
  • ⑦ ⑧两种不同的绝对定位方法

垂直居中, 共提供了8种方法.

  • ① 单行文本, line-height
  • ② 行内块级元素, 使用 display: inline-block, vertical-align: middle; 加上伪元素辅助实现
  • ③ vertical-align
  • ④ flex
  • ⑤ 盒模型
  • ⑥ transform
  • ⑦ ⑧ 两种不同的绝对定位方法

我们发现, flex, 盒模型, transform, 绝对定位, 这几种方法同时适用于水平居中和垂直居中.