本文轉載自 https://www.cnblogs.com/jiekk/p/5802147.html,個人參考着實現了效果並總結如下,如果喜歡請給原作者評論分享~
1.引言
div的垂直水平居中應該是很常見的問題了,網上的方法也很多~總之就是要實現下圖這個效果:
我們慢慢來,先看看實現這個效果真正的難點(坑)在哪裏~先不說具體的實現,很多人應該都熟悉margin:0 auto這個“標配”吧?這是讓div的上下margin變成0,左右margin自動計算,加上這一句很容易就能實現div的水平居中~不過爲什麼不把上下左右的margin全部設置成auto呢?這樣不就上下左右都居中了?
那麼我來解釋一下:
首先,div是一個塊級元素,寬度默認都是相對於父元素的100%,即:一個塊元素,如果我們不人爲的去設置它的寬度,他就單獨佔一行!換句話說,這一行就只有他一個元素!想讓他水平居中,左右margin設置成auto後底層很容易就可以計算出margin具體的數值應該是多少,從而達成左右居中。說到這裏,我們再去考慮垂直居中:頁面在垂直方向上塊級元素不一定只有一個,即塊級元素沒有“默認佔一列”這樣的規定,因此即使把margin設置成auto,也不能自動計算出margin到底該是多少......
瞭解了以上問題,我們便可以把中心轉移到垂直居中上面了~
2.實現
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>div居中</title>
<link rel="stylesheet" type="text/css" href="test.css">
</head>
<body>
<div class="outerDiv" style="width:250px;height:350px;border: 2px solid red;">
<div class="innerDiv" style="width: 150px;height: 150px;background-color: green;">
</div>
</div>
</body>
</html>
這是基本的佈局(還沒有實現居中),爲了直觀,我把居中相關的樣式 作爲外聯樣式,其他的直接直接作爲內聯樣式。
法1:利用display:table-cell(兼容IE8+)
.outerDiv{
display: table-cell;
vertical-align: middle;
}
.innerDiv{
margin: 0 auto;
}
原理:改變父元素基線的位置,而子元素基線都是自動與父元素基線在一行的。子div再加上margin:0 auto保證自己水平居中即可
缺點:對父元素的限制(無法設置margin等),兼容IE8及以上(因爲IE8以前的display不支持table-cell)
優點:同時有多個子元素也可以居中
思考 1:只寫vertical-align:middle可以完成子元素垂直居中嗎?
Answer:No!爲什麼?因爲:
vertical-align是用來定義行內元素(inline)的基線相對於該元素所在行的基線的垂直對齊,也就是說,vertical-align的作用是調整當前元素(前提他是行內元素,或者有行內元素的特性)基線的位置,而這個元素的子元素默認都是跟基線對齊的。vertical-align是行內元素的一個屬性(但是div是塊級元素!)。
因此,我們要想辦法讓父元素有inline的屬性,也就是讓他變成table-cell!
思考 1.1:如果不是table-cell,還有什麼方法讓父元素具有行內元素特性?
Answer:當然可以直接把父元素設置成display:inline,但是他也就完完全全是一個行內元素了,無法設置高度,寬度,margin這些......還有一點需要注意,設置成inline-block是不行的,div本身的內容還是塊級元素的特性。其他的方法我暫時沒有想到了......
法2:利用相對定位和絕對定位
第一種寫法:
.outerDiv{
position: relative;
}
.innerDiv{
position: absolute;
margin: auto;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
第二種寫法:
.outerDiv{
position: relative;
}
.innerDiv{
position: absolute;
left: 50%;
top:50%;
margin-left: -75px;/*子div寬度的一半*/
margin-top: -75px; /*子div高度的一半*/
}
原理:把父元素設置成非靜態元素,讓子元素可以相對它來進行絕對定位完成居中
優點:兼容性好
缺點:子元素只能有一個
3.小結
關於這幾種方法,法1是原理比較難理解的,法2是比較常見的,當然具體選用哪種方法看各自的需要,需要多個子div居中選法1,一個選法2,個人認爲法1的兼容性不是很突出的缺點~