44年前咱們把人送上月球,但在CSS中咱們仍然不能很好實現水平垂直居中。javascript
做者:Icarus
原文連接:xdlrt.github.io/2016/12/15/…css
水平垂直居中有相同點也有不一樣點,接下來討論常見的方式。html
如無特殊說明,如下示例html均爲:java
<div class="md-warp">
<span class="md-main"></span>
</div>複製代碼
基礎樣式爲:css3
.md-warp{
width: 400px;
height: 300px;
max-width: 100%;
border: 1px solid #000;
}
.md-main{
display: block;
width: 100px;
height: 100px;
background: #f00;
}複製代碼
須要知足三個條件:git
display:block
margin-left
和margin-right
都必須設置爲auto.md-main{
margin: 0 auto;
}複製代碼
須要知足三個條件:github
left:50%
margin-left
爲寬度的一半.md-warp{
position: relative;
}
.md-main{
position: absolute;
left: 50%;
margin-left: -50px;
}複製代碼
有些時候咱們的元素寬度可能不是固定的,不用擔憂,咱們依然可使用定位法實現水平居中,此時須要用到css3中的transform
屬性中的translate
,可使元素移動時相對於自身的寬度和高度。
須要注意,這種方法須要IE9+才能夠實現。web
.md-warp{
position: relative;
}
// 注意此時md-main不設置width爲100px
.md-main{
position: absolute;
left: 50%;
-webkit-transform: translate(-50%,0);
-ms-transform: translate(-50%,0);
-o-transform: translate(-50%,0);
transform: translate(-50%,0);
}複製代碼
對於單行文字來講,直接使用text-align: center
便可。
多行文字能夠看做一個塊級元素參考margin法和定位法。瀏覽器
和水平居中相似,只是把left:50%
換成了top:50%
,負邊距和transform
屬性進行對應更改便可。佈局
優勢:能在各瀏覽器下工做,結構簡單明瞭,不需增長額外的標籤。
.md-warp{
position: relative;
}
.md-main{
position: absolute;
/* 核心 */
top: 50%;
margin-top: -50px;
}複製代碼
運用css3中的clac()屬性能簡化部分代碼:
.md-warp{
position: relative;
}
.md-main{
position: absolute;
/* 核心 */
top: calc(50% - 50px);
}複製代碼
.md-warp{
position: relative;
}
.md-main{
position: absolute;
top: 50%;
// 注意此時md-main不設置height爲100px
-webkit-transform: translate(0,-50%);
-ms-transform: translate(0,-50%);
-o-transform: translate(0,-50%);
transform: translate(0,-50%);
}複製代碼
須要知足兩個條件:
line-height
設置成和height
的值同樣<div><span>這是一段文字</span></div>複製代碼
div{
width: 400px;
height: 300px;
border: 1px solid #000;
}
span{
line-height: 300px;
}複製代碼
以上是一些常規辦法,接下來是利用CSS3新特性實現的示例。
若是想避免使用絕對定位,咱們仍然能夠利用translate()
方法,其值恰好是元寬度和高度的一半。可是,咱們如何不使用top和left將元素從top和left移動50%的偏移量呢?
首先想到的是給margin屬性一個百分數,像這樣:
.md-main{
margin: 50% auto 0;
transform: translateY(-50%);
}複製代碼
效果以下所示:
咱們發現並無出現預想的結果,這是由於margin
的百分比計算是相對於父容器的width
來計算的,甚至包括margin-top
和margin-bottom
。
咱們若是仍然想讓元素在視窗中居中,仍是有救的。CSS3定義了一種新的單位,稱爲相對視窗長度單位。
如下摘自w3cplus
vw
是相對於視窗的寬度。與你預期恰好相反,1vw
至關於視窗寬度的1%
,而不是100%
與vw
類似的是,1vh
至關於視窗高度的1%
若是視窗的寬度小於高度,1vmin
等於1vw
,反之,若是視窗寬度大於高度,1vmin
等於1vh
若是視窗的寬度大於高度,1vmax
等於1vw
,反之,若是視窗寬度小於高度,1vmax
等於1vh
在上個示例的基礎上,咱們須要給margin
設置vh
單位:
.md-warp{
position: relative;
}
.md-main{
position: absolute;
margin: 50vh auto 0;
transform: translateY(-50%);
}複製代碼
注意:這種方法最大的侷限是隻能適用於元素在視窗中垂直居中,若是是在局部的某個地方就無能爲力了。
若是不考慮瀏覽器的兼容性,Flexbox無疑是最好的解決方案,由於它的出現就是爲了解決這樣的問題。
完成這項工做只須要兩個樣式,在須要水平垂直居中的父元素上設置display:flex
和在水平垂直居中的元素上設置margin:auto
。
.md-warp{
display:flex;
}
.md-main{
margin: auto;
}複製代碼
Flexbox的實現文本的水平垂直居中一樣很簡單。
.md-warp{
display:flex;
}
.md-main{
display: flex;
align-items: center;
justify-content: center;
margin: auto;
}複製代碼
補充:
.md-warp{
font-size: 0;
}
.md-warp:before{
content:'';
display:inline-block;
width: 0;
height:100%;
vertical-align:middle;
}
.md-main{
display:inline-block;
vertical-align:middle;
font-size: 14px;
}複製代碼
引自demo.doyoe.com/css/alignme…
首先要了解垂直方向的對齊排版需使用 vertical-align ,而且只應用於inline level, inline-block level 及 table-cells 元素上;其次 vertical-align 的對齊就基於每一個 line box(行框) 的,簡單的說,inline level元素按照 Normal flow 水平排版出一行就會造成一個line box,其高度由內容造成,若是換行,則又是另外一個line box,全部一段文本可能會分佈在多個line box裏,這些不重疊的line box被稱做爲a vertical stack of line boxes(一個垂直堆疊的線框集合)這些。
換句話說,咱們的垂直居中是要在每一個line box中進行處理。而上例中咱們想讓一行文本在名叫demo的高100px的容器裏垂直居中,這時有個問題就是demo容器並不是該行文本的line box,因此就算定義vertical-laign爲middle也沒法讓該行文本在demo容器中垂直居中。咱們知道line box的高度是由內容造成的,這時咱們能夠額外建立一個與該行文本處於同一line box的元素,同時將新增元素的高度定義爲與demo容器相同,此時line box的高度將與demo一致,文本將會在line box內垂直居中,即一樣實現了在demo容器中垂直居中。
.md-warp{
position: relative;
}
.md-main{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}複製代碼
經常使用在彈出層的定位中。
transform-style:preserve-3d
來解決,但這是一個Hack手段,不能保證它不會過期。以上各類方法稍加組合便可同時實現水平和垂直居中,這些就是平時用到較多的一些居中的方法,但願你們看完以後有收穫:)