44年前我們把人送上月球,但在CSS中我們仍然不能很好實現水平垂直居中。 作者:Icarus 原文鏈接:http://xdlrt.github.io/2016/12/15/2016 12 15 水平垂直居中有相同點也有不同點,接下來討論常見的方式。 如無特殊說明,以下示例html均為: 基礎樣式為: ...
44年前我們把人送上月球,但在CSS中我們仍然不能很好實現水平垂直居中。
作者:Icarus
原文鏈接:http://xdlrt.github.io/2016/12/15/2016-12-15
水平垂直居中有相同點也有不同點,接下來討論常見的方式。
如無特殊說明,以下示例html均為:
基礎樣式為:
.md-warp{
width: 400px;
height: 300px;
max-width: 100%;
border: 1px solid #000;
}
.md-main{
display: block;
width: 100px;
height: 100px;
background: #f00;
}
水平居中
margin法
需要滿足三個條件:
元素定寬
元素為塊級元素或行內元素設置display:block
元素的margin-left和margin-right都必須設置為auto
三個條件缺一不可。
demo:
.md-main{
margin: 0 auto;
}
定位法
需要滿足三個條件:
元素定寬
元素絕對定位,並設置left:50%
元素負左邊距margin-left為寬度的一半
demo1:
.md-warp{
position: relative;
}
.md-main{
position: absolute;
left: 50%;
margin-left: -50px;
}
有些時候我們的元素寬度可能不是固定的,不用擔心,我們依然可以使用定位法實現水平居中,此時需要用到css3中的transform屬性中的translate,可以使元素移動時相對於自身的寬度和高度。
需要註意,這種方法需要IE9+才可以實現。
demo2
.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屬性進行對應更改即可。
優點:能在各瀏覽器下工作,結構簡單明瞭,不需增加額外的標簽。
demo1:
.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);
}
demo2
.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{
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的解決方案
如果不考慮瀏覽器的相容性,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;
}
結語
絕對定位通常不是一個很好的選擇,因為它對整體的佈局影響相當的大。
在一些瀏覽器中,可能會導致元素出現略微的模糊,那是因為元素有可能被放置在半個像素位置上。我們可以通過transform-style:preserve-3d來解決,但這是一個Hack手段,不能保證它不會過時。
以上各種方法稍加組合即可同時實現水平和垂直居中,這些就是平時用到較多的一些居中的方法,希望大家看完之後有收穫:)