老生常谈之 css 居中

绝对定位居中(Absolute Centering)技术

.Absolute-Center {  
  margin: auto;  
  position: absolute;  
  top: 0; left: 0; bottom: 0; right: 0;  
}  
  • 解释:

通过以上描述,绝对居中(AbsoluteCentering)的工作机理可以阐述如下:

1、在普通内容流(normal content flow)中,margin:auto的效果等同于margin-top:0;margin-bottom:0。
W3C中写道If ‘margin-top’, or’margin-bottom’ are ‘auto’, their used value is 0.

2、position:absolute使绝对定位块跳出了内容流,内容流中的其余部分渲染时绝对定位部分不进行渲染。

Developer.mozilla.org:…an element that is positioned absolutely is taken out of the flow and thustakes up no space

3、为块区域设置top: 0; left: 0; bottom: 0; right: 0;将给浏览器重新分配一个边界框,此时该块block将填充其父元素的所有可用空间,父元素一般为body或者声明为position:relative;的容器。

Developer.mozilla.org:For absolutely positioned elements, the top, right, bottom, and left propertiesspecify offsets from the edge of the element’s containing block (what theelement is positioned relative to).

4、 给内容块设置一个高度height或宽度width,能够防止内容块占据所有的可用空间,促使浏览器根据新的边界框重新计算margin:auto

Developer.mozilla.org: The margin of the[absolutely positioned] element is then positioned inside these offsets.

5、由于内容块被绝对定位,脱离了正常的内容流,浏览器会给margin-top,margin-bottom相同的值,使元素块在先前定义的边界内居中。
W3.org: If none of the three [top, bottom,height] are ‘auto’: If both ‘margin-top’ and ‘margin-bottom’ are ‘auto’, solvethe equation under the extra constraint that the two margins get equal values.AKA: center the block vertically

这么看来, margin:auto似乎生来就是为绝对居中(Absolute Centering)设计的,所以绝对居中(Absolute Centering)应该都兼容符合标准的现代浏览器。

简而言之(TL;DR):绝对定位元素不在普通内容流中渲染,因此margin:auto可以使内容在通过top: 0; left: 0; bottom: 0;right: 0;设置的边界内垂直居中。

负外边距(Negative Margins)居中

.is-Negative {  
    width: 300px;  
    height: 200px;  
    padding: 20px;  
    position: absolute;  
    top: 50%; left: 50%;  
    margin-left: -170px; /* (width + padding)/2 */  
    margin-top: -120px; /* (height + padding)/2 */  
}

Transform 居中

.is-Transformed {   
  width: 50%;  
  margin: auto;  
  position: absolute;  
  top: 50%; left: 50%;  
  -webkit-transform: translate(-50%,-50%);  
      -ms-transform: translate(-50%,-50%);  
          transform: translate(-50%,-50%);  
}  

表格单元格(Table-Cell)居中

// HTML:
<div class="Center-Container is-Table">  
  <div class="Table-Cell">  
    <div class="Center-Block">  
    <!-- CONTENT -->  
    </div>  
  </div>  
</div>  

css:

// CSS:
.Center-Container.is-Table { display: table; }  
.is-Table .Table-Cell {  
  display: table-cell;  
  vertical-align: middle;  
}  
.is-Table .Center-Block {  
  width: 50%;  
  margin: 0 auto;  
}  

行内块元素(Inline-Block)居中

// HTML:
<div id="box">
    <div id="content">我是内容<br />我也是内容</div>
    <div id="actor">我是演员</div>
</div>

css:

// CSS:
#box { height: 400px; background: #c00;}
#content, #actor { display: inline-block; vertical-align: middle;}
#content { font-size: 12px; color: #fff;}
#actor {height: 400px; font-size: 0;}

加粗体的部分是关键所在。原理是都显示为行框的高度由最高的行内框决定。div#actor作为演员,高度指定和父元素一致。
兼容性:支持inline-block的浏览器均可。对于IE6/7,可以先使用hack方式使其支持Inline-block后,使用此方法实现垂直居中。

Flexbox居中

.box {
  display: flex;
  justify-content: center;
  align-items: center;
}