居中的美感置于当下亦不为过时。元素的居中对齐,能起到视觉聚焦的作用和避免处女座抓狂。在页面重构中,遇到最多的布局需求就是元素居中,因此作此总结。
假设以下实例的HTML代码均为:
HTML:

<div class="parent">
    <div class="current"></div>
</div>

一. 已知宽度元素的水平居中对齐

1. 方法1:给块级元素固定宽度,加上margin的左右值为auto;

原理:块级元素的整体宽度是自动衍生撑满父容器的。当元素的内容宽度固定后,由于块级元素依旧具有自动延伸撑满父容器的作用,所以当margin-left和margin-right值为auto时,元素会根据父容器的宽度自动减去元素的宽度,并将剩下的宽度自动分配给margin。
实例:
CSS:

.current {
    width: 100px;
    margin-left: auto;
    margin-right: auto;
}

优缺点:兼容性强,但是需要元素固定宽度;

2. 方法2:使用绝对定位的方法,让其left:50%,margin-left为-(width/2)

原理:当元素使用绝对定位时,它的左上角的顶点相对于最近的定位父元素进行布局。当left:50%时,元素与父容器的左侧的距离是50%的父容器宽度;当再给元素定义margin-left为-(width/2)时,元素向左移动自身一半的宽度,在视觉上实现了水平居中。

.parent {
    position: relative;
}
.current {
    width: 100px;
    position: absolute;
    left: 50%;
    margin-left: -50px;
}

二. 未知宽度元素的水平居中对齐

4. 方法1:利用inline-block

原理:利用inlin-block和inline元素的宽度是由自身的内容宽度动态计算出来的,并且父元素的text-align属性可以使inlin-block和inline元素实现对齐。
CSS代码:

.parent {
    text-align: center;
}
.current {
    display: inline-block;
}

优缺点:居中元素的宽度可以未知;但是由于IE6~7中的inline-block显示并非与标准浏览器的显示效果一致,需要用到CSS hack来处理。

5. 方法2:浮动实现方法

原理:给div.current元素额外添加一个父容器,并给这个父容器定位left:50%;然后让div.current元素的left为-50%,并声明为浮动元素(因为父容器div.sub-parent为行内元素,其宽度由元素的内容决定,因此div.current的宽度的50%即等于div.sub-parent宽度的50%);
div.current的"float: left"属性也可以换成"display: inline-block",效果一样。事实上浮动元素的副作用就是自动添加"display: inline-block"属性。
HTML代码:

<div class="parent">
    <div class="sub-parent">
        <div class="current"></div>
    </div>
</div>

CSS代码:

.sub-parent {
    position: relative;
    left: 50%;
    display: inline-block;
}
.current {
    positive: relative;
    left: -50%;
    float: left;/* 或者换为display: inline-block,效果相似 */
}

6. 方法3:使用CSS3中的flex

.parent {
  display: -webkit-box;
  display: -moz-box;
  display: -o-box;
  display: -ms-box;
  display: box;
  -webkit-box-orient: horizontal;
  -moz-box-orient: horizontal;
  -o-box-orient: horizontal;
  -ms-box-orient: horizontal;
  box-orient: horizontal;
  -webkit-box-pack: center;
  -moz-box-pack: center;
  -o-box-pack: center;
  -ms-box-pack: center;
  box-pack: center;
}

优缺点:扩展性好;但兼容性差,不兼容IE6~8;

7. 方法4:使用CSS3中的fit-content

原理:原理与固定宽度定义margin为auto的原理一致。只是CSS3中的fit-content属性值可以使块级元素自动根据内容来自调整自身宽度。

.current {
  width:-webkit-fit-content;
  width: -moz-fit-content;
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
}

优缺点:扩展性好;但是不兼容IE~8;

三. 已知高度元素的水平居中对齐

1. 方法1:使用绝对定位

原理与上面方法2类似。通过top:50%和margin-top:-(width/2)来定位。

.parent {
    position: relative;
}
.current {
    height: 100px;
    position: absolute;
    top: 50%;
    margin-top: -50px;
}

2. 方法2:元素绝对定位,使其top:0,bottom:0,margin-top:auto,margin-bottom:auto

CSS代码:

.parent {
    width: 100%;
    height: 500px;
    position: relative;
}
.current {
    position: absolute;
    top: 0;
    bottom: 0;
    height: 300px;
    margin: auto;
}

四. 未知高度元素的水平居中对齐

1.方法1:单行文本的垂直居中,使其line-height与height相等

原理:单行文本的line-height属性具有使文本居中的功能。
CSS代码:

.current {
    line-height:44px;
    height: 440px;
}

缺点:只适合单行文本;

2. 方法2:模拟表格效果

原理:利用表格布局中的子元素使用"vertical-align:middle"可以使元素垂直居中。

.parent {
    display: table;
}
.current {
    display: table-cell;
}

缺点:由于IE6~7中不支持"display: table",因此需要使用一些css hack来实现兼容性;

3. 方法3:利用inline-block的vertical-align属性和空盒子撑满父容器的高度

HTML代码:

<div class="parent">
    <div class="current"></div>
    <div class="actor"></div>
</div>

CSS代码:

.parent {
    height: 500px;
}
.current, .actor {
    display: inline-block;
    vertical-align: middle;
}
.actor {
    height: 500px;
    font-size: 0;
}

4. 方法4:使用translateY属性

原理:translate属性中的百分数单位是根据自身的宽度计算的。
CSS代码:

.current {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

优缺点:不兼容IE6~8;

五. 用JavaScript控制元素的居中对齐

使用javascript进行居中定位的实现居中对齐最有效的方法,同时也是比较危险的。当用户禁止使用javascript时,那么布局将有可能混乱。因此得斟酌着使用。
原理:让父元素相对定位,居中元素绝对定位。通过IavaScript动态计算出居中元素的宽度,然后算出居中元素的left值为(父容器的宽度 – 居中元素的宽度)/2,top值为(父容器的高度 – 居中元素的高度)/2。
HTML代码:

<div class="parent" id="parent">
    <div class="current" id="parent"></div>
</div>

CSS代码:

.parent {
    position: relative;
}
.current {
    position: absolute;
}

JavaScript代码:

var parent = document.getElementById("parent");
var current = parent.getElementById("current");

current.style.top = (parent.offsetHeight - current.offsetHeight) / 2 + "px";
current.style.left = (parent.offsetWidth - current.offsetWidth) / 2 + "px";
本文作者:子匠_Zijor,转载请注明出处:http://www.dengzhr.com/frontend/css/241