垂直居中作為一個常見布局形式,或多或少的會給不熟悉頁面布局的人帶來困擾,這里參考Steven Bradley總結(jié)的六種布局方法,帶給大家一些新的思考。這里介紹的方法都是常規(guī)的CSS方法,可以垂直居中行內(nèi)元素以及塊級元素,實(shí)際上CSS3的flex布局方法可以完美解決類似垂直居中,水平居中,分散對齊等常見的布局形式,具體可以參看阮一峰老師的這篇文章Flex 布局教程。
正文
通過CSS實(shí)現(xiàn)水平居中相當(dāng)簡單。當(dāng)被居中的元素是內(nèi)聯(lián)元素(行內(nèi)元素)時,我們可以使用text-align:center
在父元素中水平居中。當(dāng)元素是一個塊級元素時,我們給定它的寬度,然后把它的左邊距和右邊距設(shè)置成auto
,也可以實(shí)現(xiàn)水平居中。
考慮到text-align:center
可以水平居中,為了垂直居中大部分人首先想到的應(yīng)該是vertical-align屬性。看起來很符合邏輯,如果你熟悉表格布局,你很有可能使用過valign
屬性,這樣也會讓你相信vertical-align
應(yīng)該也是這樣。
然而valign
只對表格單元有效,vertical-align
也是類似的,它即對表格單元有效,又對一些內(nèi)聯(lián)元素有效。
vertical-align
值的意義和其父級內(nèi)聯(lián)元素有關(guān)。
- 在一行文本內(nèi),其值是相對于行高的。
- 在一個表格單元內(nèi),其值是相對于表格高度算法,通常是指一行的高度。
很遺憾vertical-align
對塊級元素不起作用,像一個div里面的段落。我們大多數(shù)可以想出來,這并不是所有的解決方案。
盡管我們有其他方法居中塊級元素,我們?nèi)匀豢梢栽谇‘?dāng)?shù)臅r候使用vertical-align
。選擇那個方法主要依賴于你想居中在何種容器元素中。
關(guān)于vertical-align更多介紹,可以看看鑫大神的文章,點(diǎn)這里
1.line-height方法
這種方法適用于垂直居中單行文本的情況。我們要做的只是給包含文本的元素設(shè)置一個行高(line-height
),只要保證行高大于文本的字體大小就可以了。
通常情況下,文本的上下會有相同的間距,文本剛好垂直居中。
大部分方法都建議把元素的height
和元素的line-height
設(shè)置成一樣的值。我認(rèn)為設(shè)置height
是沒有必要的,但是如果僅僅設(shè)置line-height
不起作用,設(shè)置height
可能就是解決辦法(這樣看來,最好height
,line-height
都設(shè)置,并且值保持一致)。
html
<div id="parent">
<div id="child"> Text here </div>
<div>
css
#child{
line-height: 200px;
}
上面的代碼可以運(yùn)行在任意的瀏覽器中,但是它只對單行文本有效,如果文本換行你必須使用另外的方法。200px是隨意設(shè)置的,你可以設(shè)置成任意大于字體大小的值。
2.css table方法
通過在table cell元素上應(yīng)用vertical-align
屬性來實(shí)現(xiàn)。
html
<div id="parent">
<div id="child">Content here</div>
</div>
css
#parent {display: table;}
#child {
display: table-cell;
vertical-align: middle;
}
把父級div的display
設(shè)置成table
,把子級div的display
屬性設(shè)置成table-cell
。然后在子級div上應(yīng)用vertical-align
屬性,并且設(shè)置成middle
。這樣子級div就相當(dāng)于一個垂直居中的容器,你可以往里面放任意內(nèi)容包括行內(nèi)元素,塊級元素,并且這些內(nèi)容都是相對父級div元素垂直居中的。
這種方法存在兼容性問題,只對IE8+起作用。
3.absolute定位和負(fù)margin方法
這種方法適用于塊級元素,并且對任意瀏覽器都有效。唯一的要求是必須設(shè)置垂直居中的塊級元素的高度。
其實(shí)用這種方式既可以垂直居中塊級元素,又可以水平居中塊級元素;垂直居中塊級元素,那么塊級元素必須設(shè)置高度;水平居中塊級元素,那么塊級元素必須設(shè)置寬度。
html
<div id="parent">
<div id="child">Content here</div>
</div>
css
#parent {position: relative;}
#child {
position: absolute;
top: 50%;
left: 50%;
height: 30%;
width: 50%;
margin: -15% 0 0 -25%;
}
首先設(shè)置父級以及子級div的position
屬性;然后把子級div的top
屬性left
屬性都設(shè)置為50%,這樣的話子級div快的左頂點(diǎn)就在父級div塊的中間位置了;接下來要做的就是把子級div往上移動其半個高度,往左移動其半個寬度,此時子級div塊才算在父級div塊的中間了。這也是為什么一定要先知道子級div塊高度和寬度的原因。
為了做到上面的第三步,可以設(shè)置子級div塊的top margin
等于負(fù)的高度的一半,left margin
等于負(fù)的寬度的一半。
和第二種方法不同,這種方法適用與塊級元素。然而如果子級div的大小比父級div的大小要大,那么子級div會有一部分內(nèi)容看不到,所以使用這種方式你最好知道子級div塊的寬高。
4.absolute定位和拉伸方法
使用這種方式必須把父級元素設(shè)置成relative
定位,把子級元素設(shè)置為absolute
定位。
下面的代碼既可以垂直居中,也可以水平居中。
html
<div id="parent">
<div id="child">Content here</div>
</div>
css
#parent {position: relative;}
#child {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 50%;
height: 30%;
margin: auto;
}
這種方法的原理是通過設(shè)置子元素距父元素4條邊的top
,left
,bottom
,right
值為0,而讓子元素自動向四條邊拉伸,因?yàn)樽衷乇雀冈匾。圆荒苡|碰到任意一條邊。
把margin
設(shè)置成auto
,可以讓每個相對邊的margin
值一樣,這樣就可以讓字div在父div中居中。
另外這種方法不支持IE8以下版本的IE瀏覽器,并且也有上面的方法中存在的問題,就是如果字元素中內(nèi)容很長,會導(dǎo)致超出內(nèi)容不可見。
5.設(shè)置相同的padding-top和padding-bottom方法
在上面的方法中,我們讓瀏覽器自動設(shè)置子元素的margin
值,所以可以保證margin值是相同的。這個方法要做的也類似,只不過要確切的設(shè)置父元素的top
和bottom
的padding
值。
html
<div id="parent">
<div id="child">Content here</div>
</div>
css
#parent {
padding: 5% 0;
}
#child {
padding: 10% 0;
}
在上面的css中子元素父元素都設(shè)置了padding-top
和padding-bottoom
值。設(shè)置子元素的padding
可以確保子元素的內(nèi)容垂直居中,設(shè)置父元素的padding
可以確保整個子元素在父元素中居中。
示例中使用了相對單位,允許每個div的padding
自動變化。如果需要設(shè)置絕對地址,你需要計(jì)算出正確的padding
值。設(shè)置子元素的padding
可以確保子元素的內(nèi)容垂直居中,設(shè)置父元素的padding
可以確保整個子元素在父元素中居中。
例如,如果父元素的高度是400px,子元素的高度是100px,那么子元素和父元素的padding-top
和padding-bottom
值應(yīng)該設(shè)置為150px。
150 + 150 + 100 = 400
此時如果還用百分比的話,就不能居中了,除非這個百分比算出來的值剛好等于150px。
這個方法適用于所有的瀏覽器。缺點(diǎn)就是有點(diǎn)計(jì)算量。
注意:這種方法是通過設(shè)置包裹元素的padding
來實(shí)現(xiàn)的,這樣的話,你就不用再設(shè)置內(nèi)部元素有相同的margin了。這里雖然使用了padding
來實(shí)現(xiàn),實(shí)際上也可以設(shè)置margin
來實(shí)現(xiàn),主要依賴代碼需要。
6.浮動div方法
最后一種方法需要一個空的浮動的div,用來控制子元素在文檔流的那個位置。注意浮動div必須在子元素前面。
html
<div id="parent">
<div id="floater"></div>
<div id="child">Content here</div>
</div>
css
#parent {height: 250px;}
#floater {
float: left;
height: 50%;
width: 100%;
margin-bottom: -50px;
}
#child {
clear: both;
height: 100px;
}
設(shè)置一個浮動的子div元素,并且設(shè)置其高度等于父div元素的50%。這樣子div元素就會充滿父div元素的上半部分。
因?yàn)檫@個子div元素從正常的文檔流中移除了,所以我們需要清除其它子元素兩邊的浮動,這里使用了clear:both
,但是實(shí)際上只需要清除和浮動元素相同方向上的浮動就可以了。
此時另一個非浮動子div元素的上邊框應(yīng)該與浮動子div元素的下邊框重合,然后需要把非浮動子div元素往上移動其高度的一半,可以通過設(shè)置浮動子div元素的margin-bottom
值為負(fù)的非浮動子div元素高度的一半來實(shí)現(xiàn)。
這種也適用于所有瀏覽器,但是缺點(diǎn)就是需要一個空的浮動div元素,然后你需要知道子div元素的高度。