CSS垂直居中的11種實現方式

今天是鄧呆呆球衣退役的日子,在這個頗具紀念意義的日子裏我寫下自己的第一篇博客,還望前輩們多多提攜,多多指教!

  接下來,就進入正文,來說說關於垂直居中的事。(以下這11種垂直居中的實現方式均爲筆者在日常的開發過程中總結得到,如發現和您的觀點確有雷同之處,那麼實在榮幸能和前輩們英雄所見略同!)

  另:這裏的demo都只是針對現代瀏覽器所做,未兼容低版本的IE以及其它非主流瀏覽器。

 

11種實現方式分別如下:

1. 使用絕對定位和負外邊距對塊級元素進行垂直居中
html代碼:
<div id="box">
    <div id="child">我是測試DIV</div>
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
    position: relative;
}
#child {
    width: 150px;
    height: 100px;
    background: orange;
    position: absolute;
    top: 50%;
    margin: -50px 0 0 0;
    line-height: 100px;
}
複製代碼

運行結果如下:

  這個方法兼容性不錯,但是有一個小缺點:必須提前知道被居中塊級元素的尺寸,否則無法準確實現垂直居中。
 
2. 使用絕對定位和transform
html代碼:
<div id="child">
    我是一串很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的文本
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
    position: relative;
}
#child {
    background: #93BC49;
    position: absolute;
    top: 50%;
    transform: translate(0, -50%);
}
複製代碼

運行結果如下:

  這種方法有一個非常明顯的好處就是不必提前知道被居中元素的尺寸了,因爲transform中translate偏移的百分比就是相對於元素自身的尺寸而言的。
 
3. 另外一種使用絕對定位和負外邊距進行垂直居中的方式
 html代碼:
<div id="box">
    <div id="child">我也是個測試DIV</div>
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
    position: relative;
}
#child {
  width
: 50%; height: 30%; background: pink; position: absolute; top: 50%; margin: -15% 0 0 0; }
複製代碼

運行結果如下:

  這種方式的原理實質上和前兩種相同。補充的一點是:margin的取值也可以是百分比,這時這個值規定了該元素基於父元素尺寸的百分比,可以根據實際的使用場景來決定是用具體的數值還是用百分比。
 
4. 絕對定位結合margin: auto
html代碼:
<div id="box">
    <div id="child">呆呆今天退役了(。﹏。)</div>
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
    position: relative;
}
#child {
    width: 200px;
    height: 100px;
    background: #A1CCFE;
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    line-height: 100px;
}
複製代碼

運行結果如下:

  這種實現方式的兩個核心是:把要垂直居中的元素相對於父元素絕對定位,top和bottom設爲相等的值,我這裏設成了0,當然你也可以設爲99999px或者-99999px無論什麼,只要兩者相等就行,這一步做完之後再將要居中元素的margin設爲auto,這樣便可以實現垂直居中了。
  被居中元素的寬高也可以不設置,但不設置的話就必須是圖片這種自身就包含尺寸的元素,否則無法實現。
 
5. 使用padding實現子元素的垂直居中
html代碼:
<div id="box">
    <div id="child">今天西安的霾嚴重的嚇人,剛看了一眼PM2.5是422</div>
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    background: #ddd;
    padding: 100px 0;
}
#child {
    width: 200px;
    height: 100px;
    background: #F7A750;
    line-height: 50px;
}
複製代碼

運行結果如下:

  這種實現方式非常簡單,就是給父元素設置相等的上下內邊距,則子元素自然是垂直居中的,當然這時候父元素是不能設置高度的,要讓它自動被填充起來,除非設置了一個正好等於上內邊距+子元素高度+下內邊距的值,否則無法精確的垂直居中。
  這種方式看似沒有什麼技術含量,但其實在某些場景下也是非常好用的。
 
6. 設置第三方基準
html代碼:
<div id="box">
    <div id="base"></div>
    <div id="child">今天寫了第一篇博客,希望可以堅持寫下去!</div>
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
}
#base {
    height: 50%;
    background: #AF9BD3;
}
#child {
    height: 100px;
    background: rgba(131, 224, 245, 0.6);
    line-height: 50px;
    margin-top: -50px;
}
複製代碼

運行結果如下:

  這種方式也非常簡單,首先設置一個高度等於父元素高度一半的第三方基準元素,那麼此時該基準元素的底邊線自然就是父元素縱向上的中分線,做完這些之後再給要垂直居中的元素設置一個margin-top,值的大小是它自身高度的一半取負,則實現垂直居中。
 
7. 使用flex佈局
html代碼:
<div id="box">霧霾天氣,太久沒有打球了</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
    display: flex;
    align-items: center;
}
複製代碼

運行結果如下:

這種方式同樣適用於塊級元素:

html代碼:

<div id="box">
    <div id="child">
        程序員怎麼才能保護好眼睛?
    </div>
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
    display: flex;
    align-items: center;
}
#child {
    width: 300px;
    height: 100px;
    background: #8194AA;
    line-height: 100px;
}
複製代碼

運行結果如下:

  flex佈局(彈性佈局/伸縮佈局)里門道頗多,這裏先針對用到的東西簡單說一下,想深入學習的小夥伴可以去看阮一峯老師的博客。(http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
  flex也就是flexible,意爲靈活的、柔韌的、易彎曲的。
  元素可以通過設置display:flex;將其指定爲flex佈局的容器,指定好了容器之後再爲其添加align-items屬性,該屬性定義項目在交叉軸(這裏是縱向軸)上的對齊方式,可能的取值有五個,分別如下:
  flex-start::交叉軸的起點對齊;
  flex-end:交叉軸的終點對齊;
  center:交叉軸的中點對齊;
  baseline:項目第一行文字的基線對齊;
  stretch(該值是默認值):如果項目沒有設置高度或者設爲了auto,那麼將佔滿整個容器的高度。
 
8. 第二種使用彈性佈局的方式
html代碼:
<div id="box">
    <div id="child">
        答案當然是多用綠色的背景哈哈
    </div>
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
#child {
    width: 300px;
    height: 100px;
    background: #08BC67;
    line-height: 100px;
}
複製代碼

運行結果如下:

  這種方式也是首先給父元素設置display:flex,設置好之後改變主軸的方向flex-direction: column,該屬性可能的取值有四個,分別如下:
  row(該值爲默認值):主軸爲水平方向,起點在左端;
  row-reverse:主軸爲水平方向,起點在右端;
  column:主軸爲垂直方向,起點在上沿;
  column-reverse:主軸爲垂直方向,起點在下沿。
  
  justify-content屬性定義了項目在主軸上的對齊方式,可能的取值有五個,分別如下(不過具體的對齊方式與主軸的方向有關,以下的值都是假設主軸爲從左到右的):
  flex-start(該值是默認值):左對齊;
  flex-end:右對齊;
  center:居中對齊;
  space-between:兩端對齊,各個項目之間的間隔均相等;
  space-around:各個項目兩側的間隔相等。
 
9. 還有一種在前面已經見到過很多次的方式就是使用 line-height 對單行文本進行垂直居中
html代碼:
<div id="box">
    我是一段測試文本
</div>

css代碼:

複製代碼
#box{
    width: 300px;
    height: 300px;
    background: #ddd;
    line-height: 300px;
}
複製代碼

運行結果如下:

  這裏有一個小坑需要大家注意:line-height(行高) 的值不能設爲100%,我們來看看官方文檔中給出的關於line-height取值爲百分比時候的描述:基於當前字體尺寸的百分比行間距。所以大家就明白了,這裏的百分比並不是相對於父元素尺寸而言,而是相對於字體尺寸來講的。
 
10. 使用 line-height 和 vertical-align 對圖片進行垂直居中
html代碼:
<div id="box">
    <img src="duncan.jpeg">
</div>

css代碼:

複製代碼
#box{
    width: 300px;
    height: 300px;
    background: #ddd;
    line-height: 300px;
}
#box img {
    vertical-align: middle;
}
複製代碼

運行結果如下:

vertical-align並不像看起來那樣天真無邪童叟無欺,以後會單獨拎出來專門寫一篇。
 
11. 使用 display 和 vertical-align 對容器裏的文字進行垂直居中
html代碼:
<div id="box">
    <div id="child">我也是一段測試文本</div>
</div>

css代碼:

複製代碼
#box {
    width: 300px;
    height: 300px;
    background: #ddd;
    display: table;
}
#child {
    display: table-cell;
    vertical-align: middle;
}
複製代碼

運行結果如下:

  這裏關於vertical-align囉嗦兩句:vertical-align屬性只對擁有valign特性的html元素起作用,例如表格元素中的<td><th>等等,而像<div><span>這樣的元素是不行的。

  valign屬性規定單元格中內容的垂直排列方式,語法:<td valign="value">,value的可能取值有四種:

  top:對內容進行上對齊
  middle:對內容進行居中對齊
  bottom:對內容進行下對齊
  baseline:基線對齊
 
  關於baseline值:基線是一條虛構的線。在一行文本中,大多數字母以基線爲基準。baseline 值設置行中的所有表格數據都分享相同的基線。該值的效果常常與 bottom 值相同。不過,如果文本的字號各不相同,那麼 baseline 的效果會更好。
 
 
  PS:一個人的力量畢竟有限,所以也難以保證百分之一百的合理性與正確性,如在閱讀的過程中發現有描述不當的地方,或者您有更好的實現方式,那麼歡迎隨時指正,隨時留言,筆者不勝感激!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章