关于网页中的垂直居中

Posted by Nutlee on 2016-06-10

 

在网页制作中常会遇到水平居中和垂直居中的场景,相对而言,水平居中较简单,而垂直居中则较麻烦些,而且垂直居中要考虑的情况很多。下面本文就从使用的角度按综合难易程度和优雅性介绍几种方案。
以下代码均测试过可以完美运行。

icon和文字的垂直居中 (近似居中)

这种情况一般是比较小的局部内容,将容器的height和line-height设置为一致就能保证内部元素 “近似居中”。说是近似居中的原因在于,行内元素默认是base-line(基线)对齐,多数情况下基线只是 约等于 容器的“中线”,虽然不是绝对的居中,但是对于icon和文字对齐这种情况已经够用,如果非要追求完全垂直居中,就要操作 vertical-align 属性。(参见下面 4.inline-block 方法)

完全居中

个人看来最佳的方案,虽然没有想象的百分之百灵活,但是已经适用于绝大部分情况了。

  • 优点:兼容性较好,现代浏览器&IE8+,使用非常简便,不用手动计算margin/padding/width/height。
  • 缺点:不能撑开父容器( 即:父容器需要定高 ),当然居中的对象也要明确高度的,需要position: absolute。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <style>
    .container {
    position: relative;
    height: 500px;
    background-color: grey;
    }
    .center {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    height: 300px;
    width: 200px;
    margin: auto;
    background-color: yellow;
    /*overflow: hidden;*/
    }
    </style>
    <div class="container">
    <div class="center"></div>
    </div>



    如图



使用display: table-cell

从使用效果上看应该是最完美的方式。

  • 优点:兼容性好,现代浏览器&IE8+,通用性好便于移植,可以撑开父容器。
  • 缺点:需要额外套一层无语义标签,不够简洁。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <style>
    .container {
    display: table;
    height: 200px;
    margin: 0 auto;
    background-color: grey;
    }
    .wrap {
    display: table-cell;
    vertical-align: middle;
    }
    .center {
    width: 100px;
    background-color: yellow;
    /*overflow: hidden;*/
    }
    </style>
    <div class="container">
    <div class="wrap">
    <div class="center">文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器</div>
    </div>
    </div>

    如图 ( 同时设置了水平居中 )



    文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器


inline-block 方法 1

利用 1.icon和文字的垂直居中 中提到的 inline 元素内部的垂直居中规则。为了做到 完全垂直居中 需引入空的inline标签如 ““,同时操作 vertical-aligin: middle 将基线和容器的中线保持一致。

  • 优点:兼容性好,现代浏览器&IE8+&IE7*,通用性好便于移植,可以撑开父容器。
  • 缺点:需引入无语义空 inline 标签,还有如果父容器不是 inline/inline-block 元素要改变父容器 display 属性,有可能造成其他不确定的后果,IE7下需要hack让元素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
    <style>
    .container {
    height: 200px;
    text-align: center;
    background-color: grey;
    }
    .center {
    display: inline-block;
    width: 100px;
    vertical-align: middle;
    /*text-align: initial;*/
    background-color: yellow;
    }
    .container i {
    display: inline-block;
    height: 100%;
    vertical-align: middle;
    }
    </style>
    <div class="container">
    <div class="center">文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器</div>
    <i></i>
    </div>

    如图 ( 同时设置了水平居中 )

    文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器


    此方法有两点要注意

    1. 父容器内部不能有其他的inline元素干扰中线对齐,即不能用默认base-line对齐的元素存在或者不是 vertical-align:middle 。
    2. 也可以设置父容器 font-size: 0 ,这样也是为了使容器内中线和基线位置一致,当容器内需要文字时再单独设置其font-size,即可省去无语义 i 标签。

inline-block 方法 2

基本原理等同于1,不过使用伪类 :after { content: “”} 构造空的 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
<style>
.container {
height: 500px;
text-align: center;
background-color: grey;
}
.container:after {
content: "";
display: inline-block;
height: 100%;
margin-left: -0.25em; /* To offset spacing. May vary by font */
vertical-align: middle;
}
.center {
display: inline-block;
width: 100px;
max-width: 99%; /* Prevents issues with long content causes the content block to be pushed to the top */
/* max-width: calc(100% - 0.25em) /* Only for IE9+ */
vertical-align: middle;
/*text-align: initial;*/
background-color: yellow;
}
</style>
<div class="container">
<div class="center">文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器文字为了撑开容器</div>
</div>

如图 inline-block 方法 1 中图效果。

负margin

7.空div方式异曲同工,常用于兼容性要求极为苛刻时,简单粗暴。

  • 优点:兼容性极佳,甚至兼容IE6~7,使用方式固定、简单。
  • 缺点:每次都要计算负margin值,不够灵活,不能适应响应式设计,实现粗暴。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <style>
    .container {
    position: relative;
    height: 300px;
    background-color: grey;
    }
    .center {
    position: absolute; /** 若此处使用relative,父容器要BFC,同时注意此元素会在文档流中的占位。 **/
    top: 50%;
    left: 50%;
    margin-top: -50px; /* 自身高度的一半*/
    margin-left: -50px;
    height: 100px;
    width: 100px;
    background-color: yellow;
    }
    </style>
    <div class="container">
    <div class="center"></div>
    </div>

    如图 ( 同时设置了水平居中 )



空div撑开

6.负margin方式异曲同工,常用于兼容性要求极为苛刻时(IE6),简单粗暴。

  • 优点:兼容性极佳,使用方式固定、简单。
  • 缺点:每次都要计算撑开的div容器值,不够灵活,空标签冗余,实现粗暴,不能撑开父容器,使用场景非常局限,不推荐使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <style>
    .container {
    position: relative;
    height: 300px;
    background-color: grey;
    }
    .filling {
    height: 50%;
    }
    .center {
    position: absolute;
    margin-top: -50px; /* 自身高度的一半*/
    height: 100px;
    width: 100px;
    background-color: yellow;
    }
    </style>
    <div class="container">
    <div class="filling"></div>
    <div class="center"></div>
    </div>

    如图 ( 仅展示垂直居中 )

    Flexbox

  • 优点:使用极其简单。

  • 缺点:兼容性要求高现代浏览器&IE10+,不能撑开父容器。

参考资料:
我个人在百度前端学院课程中做的练习–>传送门
如何只用CSS做到完全居中
CSS 实现垂直居中的 5 种方法