上下居中的處理方式

炎藤發表於2015-04-12

1. 幽靈槓桿法(推薦)

我最早是在中國的網站上看到的,這種方法看似比較簡單,實際上還是很有內涵的。簡單的說是就是通過新增一個有高度的隱形元素來撐高整個 DIV。深入一些,這裡用一個 inline-block 就解決了相容問題了。這是我目前看到的最簡單的,並且又能實現相容的方案。

<style>
 .wrap {
    height:100px; 
    border:solid 1px #999;
 }    
 .lever {
    vertical-align:middle; 
    display:inline-block; /*IE7+ 必須*/
    height:100%; 
    width:0px;  
    background-color: red;
 }    
 .textSpan {
    vertical-align:middle;
 }
</style>

原理分析:

a) 基本原理

通過前面 .lever 的 100% 高度(height: 100%)的中心線的調整(vertical-align:middle)來實現整個 div 的佈局上下居中。

b) 相容處理

在 IE7+ 的瀏覽器中,如果 span 裡面沒有內容,預設下的 display: inline 是不管高寬設定的。當然,你可以給它一個 padding 來設定這個高度,這時候瀏覽器會以 1em (Chrome 瀏覽器預設下是 1em 高度大概是 16px) 高度去計算。這顯然無法達到我們的目的,所以要讓他可以設定 100% 高度的話,就要新增了一個 display: inline-block。

c) 細微事項 預設下 vertical-align 的值是 baseline,不過 IE7 中是沒有 baseline 的所以就變成了 bottom,所以 IE7+ 和 IE7/IE7- 會有一些細微的不一樣的地方。

IE7+ Baseline

IE7+ 的效果

IE7/IE7- Bottom

IE7/IE7- 的效果

不過這些都無法阻止我們上下居中了,因為他們的 middle 都是相同的:

(IE7) = (IE7+.A) + (IE7+.B) (IE7)/2 = (IE7+.A)/2 + (IE7+.B)/2

看到有一些人用 <img> 來代替 <span> 的寫法,其實這個是不符合語義的,應該用 span 或者 div 去處理顯示佈局的問題。

國外的 CSS-Tricks 上也分享了類似的編寫方式,叫做 Ghost,通過 :before 選擇器完成,不過由於 IE7 是不支援 :before 選擇器的,有對舊瀏覽器考量的同學(特別是為某些非盈利機構服務的),就要慎重選擇了。

2. Table 模擬法

這個也是非相容性方案,IE7 以下也都不支援該方法,不過對於 IE7+ 的瀏覽器倒是很方便,習慣 Table 佈局的長輩們應該會喜歡這種簡單方便的處理方式,程式碼如下:

CSS:

<div class="something-semantic">
   <div class="something-else-semantic">
       Unknown stuff to be centered.
   </div>
</div>

HTML:

.something-semantic {
  display: table;
  width: 100%;
}
.something-else-semantic {
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}

3. 計演算法

通過 position 設定 absolute 的方式來處理,也是可以實現相容多個瀏覽器,不過... 要對每個元素進行計算高度,手動設定,這種方式還是比較費工夫的。

<!DOCTYPE html>
<head>
<style>
body{
    margin:0;
    padding:0;
    width:100%;
    height:100%;
}
div{
    position:absolute;
    top:50%;
    left:50%;

    /*寬和高都要固定*/
    width:500px;
    height:18px;

    /*寬高反向位移 50%*/
    margin-top:-9px;
    margin-left: -250px;
    background-color: #ecf;
}
</style>
</head>
<body>
    <div>TEST</div>
</body>

類似的還有 phrogz 的夾層計算,更加複雜一些,不過其實原理也是通過計算 margin 來實現,是比較多人提起到的:

1) http://www.blueidea.com/tech/web/2006/3231.asp
2) http://www.andy-howard.com/verticalAndHorizontalAlignment/index.html

4. line-height

這個只能處理單行的上下居中,多行就難看了。

5. CSS3 處理法

槓桿法或者 Table 法給人的感覺像是作弊,CSS3 的寫法感覺會更正規一些。CSS3 Transform 是比較潮的寫法,程式碼比較簡單,輕鬆搞定居中問題,當然相容性上嘛,也是存在比較多的問題的(我覺得對照表還是偏心非 IE 瀏覽器的,比如 IE 瀏覽器列出好幾個版本,並且都是過時的版本,而非 IE 瀏覽器往往都是最新版本;當然另外一方面也是因為 IE 瀏覽器仍然佔據瀏覽器市場較大比例的原因)。

CSS3 transform 相容表

其原理其實是和 IE7 相容處理是一樣的道理的,先通過 top: 50% 位居中線,然後調整內部的 Element 上移50%,程式碼如下:

<style>
.text p {
  position: relative;
  top: 50%;
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}
.text {
    height: 100px;
    background-color: #396;
}
</style>
<div class="text">
  <p>I'm vertically aligned! Hi ho Silver, away!</p>
</div>

參考資料:
1. http://davidwalsh.name/css-vertical-center
2. http://www.vanseodesign.com/css/vertical-centering
3. http://www.vertical-align.com <- 還有人專門為這個問題搭建了網站?!
4. http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css
5. http://www.codesky.net/article/201109/169418.html

相關文章