CSS是HTML元素的剪刀手,它極度的豐富了web頁面的修飾。在眾多CSS常見的樣式需求中,有一奇葩式的存在【垂直居中】,因為不管是從邏輯實現方面還是從正常需求量來講,這都沒理由讓這個需求在實踐過程中,顯的那么艱難。我們往往需要額外添加標簽元素與充滿hack味道的屬性才能解決,而在涉及到不固定元素尺寸的時候,更顯艱難。唉,日子還得照樣過,工作還得繼續干,這里就從實際需求的角度來歸納一些純CSS方案。【特別說明,現實中的需求千變萬化,請閱者根據實際需求】
文本內容的垂直居中這是一個爛大街的需求,比如在頁面中某一塊內容的標題上和單行列表上就會有用到。如下圖:

現在我們就假設需要在一個寬400px,高32px的div上,使里面的一行文字垂直居中,主要效果如下圖:

實現上面需求的HTML代碼如下:
<div class="box"><span>標題標題</span></div>
CSS實現的代碼如下:
.box{ width: 400px; background-color: #ccc; color: #333; line-height:32px; /*主要實現代碼*/ }
實現上面的需求,我們還可以用內填充來解決。不過用這個方法得事先了解我們事先的css reset或者瀏覽器對頁面設置的默認行高是多少。假設為24px,那么我們把32px高度減去默認行高的24px,然后除以2得到4px,然后用內填充填上,所以我們可以改成這樣:
.box{ width: 400px; background-color: #ccc; color: #333; padding: 4px 0; /*主要實現代碼*/ }
這樣麻煩是麻煩了點,但總解決了問題。
需求是永無止境的,上面是實現了單行的文本問題,如果我們要實現多行文本的內容的垂直居中該怎么辦呢?如下圖,一個寬400px,高300px的div:

上面實現的HTML代碼如下:
<div class="box"> <p>標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題</p> </div>
你肯定想到了用內填充來解決這個問題,畢竟是固定高度的(代碼就不附上了),可是如果我們里面的內容再多增加一行,或者減去一行,這種方法就行不通了。這時,我們就可以利用table的特性來解決;
.box{ height:300px; width: 400px; background-color: #ccc; color: #333; display: table; /*設置父標簽為table展示*/ } .box > p{ display: table-cell;/*設置子標簽為表格的單元格*/ vertical-align: middle;/*設置子標簽單元格展現內容方式*/ }
這種方法是在IE7以及以下是沒有用的,因為它們不支持標簽轉變為table的變化,即 display: table; 與display: table-cell;當然你可以直接用表格布局,這無所謂。好在聰明人很多,我們前端的前輩們研究了另外一種方法來實現上述內容,但html結構有變化,具體如下:
<!--html代碼--> <div class="box"> <div> <div><p>標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題標題</p></div> </div> </div> <!--css代碼--> <style> .box{ width: 400px; height: 300px; position: relative; background-color: #ccc; color: #333; } .box > div{ position: absolute; top: 50%; left: 0; } .box > div > div{ position: relative; top: -50%; left: 0; } </style>
這只適用IE7及以下,隨着瀏覽器的不斷升級,我們可能不需要兼容這么低版本的瀏覽器,當做一種了解吧。
像上面的利用table的特性來布局,里面的內容是包括div和圖片的。這個可以自己試試,放入固定高寬的塊級元素和圖片。(注意一點,p標簽里面放入div,在一些瀏覽器中實際顯示中會把p標簽分割成兩個,所以你可以把子元素改成div)
而如果單單你只想圖片的垂直居中,你可以使用如下的方式:
<!--html代碼--> <div class="box1"> <img src="xxxxx.png"> </div> <!--css代碼--> <style> .box1{ background-color: #ccc; line-height: 300px; width: 400px; } .box1 > img{vertical-align: middle;} </style>
具體效果自己看吧。
以上都是文本內容的垂直居中,但是我們平時工作中用的多的還有另外一種情況,即盒子居中,即div居中。如下圖,下圖是一個div,寬400px,高300px:

聰明如你,一定會用到了table來解決。這也是一種解決方案,我們還可以用定位來解決方法,如:
.box{ height:300px; width: 400px; background-color: #ccc; color: #333; position: absolute;/*這里也可以使用fixed,看自己情況而定*/ top: 50%; left: 50%; margin:-150px 0 0 -200px; }
或者你也可以使用下面的代碼
/*代碼不適用與IE7及以下*/
.box{ height:300px; width:400px; background-color: #ccc; color: #333; position: fixed;/*這里也可以使用fixed,看自己情況而定*/ top:0; left:0; bottom:0; right:0; margin:auto; }
以上方法都需要一個固定的高度的,如果們不確定內容的高度該怎么實現呢?利用上面的table是可以辦到的,如果你的項目不用兼容不支持CSS3的瀏覽器話,可以試試以下的方法:
.box{ width:200px; background-color: #ccc; color: #333; position: fixed;/*可以切換為absolute*/ top: 50%; left: 50%; transform: translate(-50%, -50%); }
既然你的項目這么超前,我們也可以使用flexbox(伸縮盒)來布局,使用這種方法我們是可以不用指定寬度的,,代碼如下:
body { display: flex; min-height: 100vh; margin: 0; } .box { background-color: #ccc; margin: auto 20px; }
總結:這么多的方法都不是那么完美的,具體情況具體而定吧,據說CSS發展到未來,會直接用一個屬性align-self: center;來搞定所有元素的垂直居中,期待那天的到來吧。
