文本的水平垂直居中

*對一個元素水平垂直居中,在我們的工作中是會經常遇到的,也是CSS佈局中很重要的一部分,本文就來講講CSS水平垂直居中的一些方法。* 1. 文本的水平垂直居中
line-height + text-aligncenter
代碼:
<div class='wrap'>
水平垂直居中水平垂直居中
</div>
html,body{
margin: 0;
}

.wrap{
line-height: 400px;
text-align:center;

height: 400px;
font-size: 36px;
background-color: #ccc;
}
*這種方法只適合單行文字的水平垂直居中* 2.利用盒模型的水平垂直居中 我們一般講的盒模型都是說的塊級盒的盒模型,也只有塊級盒的盒模型用得多一點,塊級盒塊級盒又是分別由content-box,padding-box,border -box,緣盒組成的,如下圖: 也就說我任一個子盒子的水平和垂直方向的邊與最外面盒子的間距都是可以控制的,因此也就有如下居中方法: 填充填充 代碼:
<div class="wrap">
<div class="content"></div>
</div>
@wrapWidth : 400px;

.wrap{
margin-left: auto;
margin-right: auto;
margin-top: 20px;
width: @wrapWidth;
height: @wrapWidth;
background-color: #ccc;
}

.content{
@contentWidth : 100px;
width: @contentWidth;
height: @contentWidth;
padding: (@wrapWidth - @contentWidth) / 2;
background-color: #333;
background-clip:content-box;
}
也可以用CSS3的計算值()動態計算: DEMO鏈接
<div class="wrap">
<div class="content"></div>
</div>
.wrap{
margin-top: 20px;
margin-left: auto;
margin-right: auto;
width: 400px;
height: 400px;
background-color: #ccc;
.content{
padding: -webkit-calc(~"(100% - 100px) / 2");
padding: calc(~"(100% - 100px) / 2");
width: 100px;
height: 100px;
background-color: #333;
background-clip: content-box;
}
}
注意這裏我在calc中使用了一個〜“”的寫法,這是少中的一個語法,告訴較少這裏不被少所編譯,要被被少編譯了的話,css的calc函數的參數就不是100% 100像素,而是0%了。 緣填充 代碼:
<div class="wrap">
<div class="ele"></div>
</div>
.wrap{
@wrapHeight : 400px;
@contenHeight : 100px;
overflow: hidden;
width: 100%;
height: @wrapHeight;
background-color: #ccc;
.ele{
margin-left: auto;
margin-right: auto;
margin-top: (@wrapHeight - @contenHeight) / 2;
width: 100px;
height: @contenHeight;
background-color: #333;
color: #fff;
}
}
使用餘量填充我們需要知道元素的寬度,這點不太靈活,不過CSS3搞出了一個加適合內容的屬性值,可以動態計算元素的寬度,DEMO鏈接 使用盒模型進行佈局不會產生迴流,兼容也好,使用盒模型佈局是一種佈局思想,其實只是靠它就能實現很多視覺格式化才能實現的佈局,這是另一個話題,這裏不展開。 三。絕對佈局上下文下的水平垂直居中 50%+ -50% 原理很簡單,就是利用左:50%將盒子的左邊先置於父容器的中點,然後再將盒子往左偏移盒子自身寬度的50%,這裏有三種具體實現: DEMO鏈接
<div class="wrap">
<div class="ele margin">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div>
</div>

<div class="wrap">
<div class="ele translate">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div>
</div>

<div class="wrap">
<div class="ele relative">
<div class="ele-inner">水平垂直居中水平垂直<br>居中水平垂直居中水平<br>垂直居中水平垂直居<br>中水平垂直居中</div>
</div>
</div>
.wrap{
position: relative;
width: 100%;
height: 200px;
border:1px solid;
background-color: #ccc;
.ele{
position: absolute;
left: 50%;
top: 50%;
background-color: #333;
&.margin{
width: 160px;
height: 100px;
margin-left: -80px;
margin-top: -50px;
}
&.translate{
-webkit-transform:translate3d(-50%, -50%, 0);
transform:translate3d(-50%, -50%, 0);
}
.ele-inner{
position: relative;
left: -50%;
top: -50%;
width: 100%;
height: 100%;
background-color: #333;
}
&.relative{
width: 150px;
height: 100px;
background-color: transparent;
}
}
}
上面三個方法中,方法和相對餘量方法都需要知道元素的寬高才行(相方法只知道高也行),適用於固定式佈局,而變換方法則可以不知道元素寬高
text-aligncenter + absolute
文本aign:中心本來是不能直接作用於絕對元素的,但是沒有給其留下等值的行級絕對元素是會受文本的影響的,可以參考張老師的這篇文章 DEMO鏈接 代碼:
<div class="wrap">
<div class="ele"></div>
</div>
.wrap{
text-align: center;

width: 100%;
height: 400px;
background-color: #ccc;
font-size: 0;
}
.ele{
position: absolute;
margin-left: -(100px / 2);
margin-top: (400px - 100px) / 2;

width: 100px;
height: 100px;
display: inline-block;
background-color: #333;
}
簡單解釋下,首先,文本對齊:中心作用的是文本而不是絕對的元素,但是,當絕對元素爲內聯塊的時候,它會受到文本的影響,然後你可能會問這裏沒文本啊,我只能告訴你說這下面是有的,是個匿名的文本節點具體的這裏不展開,可以參考標準,然後理解這句話: 如果內聯框根本不包含字形,則它被認爲包含一個支撐(零寬度的不可見字形),該元素的第一個可用字體的A和D 然後這個匿名文本由於受到文本對齊:中心影響居中了,這個時候絕對盒子的左邊跟父容器的中點對齊了,所以就還需要往回拉50%,這裏用的是利潤率左,你也可以用其它方式拉。然後就是垂直方向的對齊,垂直方向是不能被操作文本的屬性影響的,所以我這裏用的是上邊距來讓它偏移下去。 絕對+邊距:自動 代碼:
<div class="wrap">
<div class="ele"></div>
</div>
html,body{
width: 100%;
height: 100%;
margin: 0;
}
.wrap{
position: relative;
width: 100%;
height: 100%;
background-color: #ccc;
.ele{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: 100px;
height: 100px;
background-color: #333;
}
}
關於這種佈局的原理,在標準中能找到如下解釋: w3c.org中有這樣一句話: 確定這些元素使用的值的約束是: ‘left’+’margin-left’+’border-left-width’+’padding-left’+’width’+’padding-right’+’border-right -width’+’margin-right’+’right’=包含塊的寬度 這句話話是絕對性質的盒子,它的包含塊的寬度等於它的盒模型的寬度+左+右值,包含塊的高度同理,盒模型包括邊框,邊框,填充盒,內容盒,而在這個居中方法中,.ele的左+右值是0,width是定值,width所在盒子包括了除了margin-box外的那三個框,margin都是auto值,按照上面那個公式,margin-left + margin-right的值應該等於包含塊的寬度 - 左的值 - right的值 - width的值,也就是說margin-left + margin-right的值等於除了width所佔寬度外的剩下寬度,擁有剩下寬度後,就是平分其寬度,以讓左右兩邊相等,達到居中,標準中給出了答案: 如果三者都不是“自動”:如果“margin-left”和“margin-right”均爲“auto”,則在額外的約束下解決方程式,即兩個邊距獲得相等的值,除非這會使它們爲負值,在這種情況下,當包含塊的方向爲’ltr’(’rtl’)時,將’margin-left’(’margin-right’)設置爲零並解決’margin-right’(’margin-left’) 這裏的“three”指的是left,width,right。如果左,右和寬都不爲汽,同時margin-left和margin-right都是auto,除非特別情況,它們倆就是相等的,而這個例子中不在特殊情況之列,因此兩者平分,此時達到了水平居中。而對於垂直方向的餘量的自動值的計算,標準中也有如下兩句話,跟水平方向的同理(這裏的“三“指的是”top,height,bottom“): 垂直尺寸的使用值必須滿足這個約束: ‘top’+’margin-top’+’border-top-width’+’padding-top’+’height’+’padding-bottom’+’border-bottom -width’+’margin-bottom’+’bottom’=包含塊的高度 如果三個都不是“自動”:如果“margin-top”和“margin-bottom”都是“auto”,則在兩個邊距獲得相等值的額外約束下求解方程。 垂直方向也就因此也居中了。 這種方法能簡單的做到居中,但是必須有寬度和高度值 適用於圖片居中的網易NEC的一個方法 DEMO鏈接 代碼:
<div class="wrap">
<p>
<img src="http://nec.netease.com/img/s/1.jpg" alt="" />
<img src="http://nec.netease.com/img/s/1.jpg" alt="" />
</p> 
</div>
html,body{
width: 100%;
height: 100%;
margin: 0;
}

.wrap{
position:relative;
width: 100%;
height: 100%;
p{
position:absolute;
left:50%;
top:50%;
}
img{
&:nth-child(1){
position:static;
visibility:hidden;
}
&:nth-child(2){
position:absolute;
right:50%;
bottom:50%;
}
}
}
這種方法主要是利用了一個圖片進行佔位,以讓父容器獲得高寬,從而讓進行-50%偏移的圖片能有一個參照容器作百分比計算。優點是可以不知道圖片的大小,隨便放張尺寸不超過父容器的圖片上去都能做到居中。另外,兼容性好,如果是不使用第n個孩子選擇器的花,IE6都是能順利兼容的 四。浮佈局上下文下的水平垂直居中 浮動+ -50% 代碼:
<div class="wrap">
<div class="ele">
<div class="ele-inner">居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中居<br>中居中居中居中居中居中居中居中居中居<br>中居中居中居中居中居中居中</div>
</div>
</div>
.wrap{
float: left;
width: 100%;
height: 400px;
background-color: #ccc;
.ele{
float: left;
position: relative;
left: 50%;
top: 50%;
}
.ele-inner{
position: relative;
left: -50%;
-webkit-transform : translate3d(0, -50%, 0);
transform : translate3d(0, -50%, 0);
background-color: #333;
color: #fff;
}
}
這種方法的原理,首先是利用浮法屬性將需要居中的元素的父元素.ele的寬度收縮,然後左:50%將.ele的左邊和水平中線對齊,這個時候還沒居中,還需要將其往回拉自身寬度的50%,於是.ele-內便是真正需要水平居中的元素,我給它一個位置:相對的,將其往回拉自身寬度的50%就行了對於垂直方向,依然是先將.ele頂部:50%到垂直方向中點,但是這時給.ele-inner top:50%是不起作用的,因爲如果沒給父元素明確高度的話,這個50%是計算不出來的,因此,就有了transform:translate3d(0,-50%,0)。 這種方法的好處是元素可以不定寬,任何時候都可以做到居中 我當時在w3cplus的站上發現這個方法後,當時覺得這個方法很好,兼容性好,又還可以不定寬,但當我用了一段時間後,發現了一個問題: 就是當居中元素的父元素左:50%時,如果元素寬度足夠大,會超出外面的容器,而如果外面的容器又正好是溢出:汽車的話,那就會在外面產生滾動條,問題DEMO鏈接在這裏,後來我找到了一個辦法:DEMO鏈接,基本思想就是利用元素超出父元素的左邊不會產生滾動條的特性,有點奇幻技巧,但是能解決問題,有興趣的可以看看 邊際底線:-50% 代碼:
<div class="wrap">
<div class="placeholder"></div>
<div class='content'></div>
</div>
.wrap{
float: left;
width: 100%;
height: 400px;
background-color: #ccc;
@contentHeight : 100px;
.placeholder{
float: left;
width: 100%;
height: 50%;
/*居中元素.content高度一半*/
margin-bottom: -(@contentHeight / 2);
}
.content{
position: relative;
left: 50%;
transform:translate3d(-50%, 0, 0);
clear: both;
/*演示用,實際不需要定寬*/
max-width: 100px;
height: @contentHeight;
background-color: #333;
}
}
這種方法是先讓佔位元素.placeholder佔據50%的高度,然後給一個居中元素高度一半的負的邊距,然後下面的元素只要跟着擺放就能垂直居中了。水平方向就是利用翻譯做偏移,這個沒什麼好說的,你也可以換成其他辦法。 這種方法就是各種固定死,首先最外層的父容器需要一個固定高度,以讓.placeholder的高度:50%有效,然後,下邊距也需要固定死,而且得需要知道居中元素高度。單純就水平方向來說,這個方法比較適合需要兼容低版本IE的固定式佈局的項目,因爲兼容性好。 五.BFC佈局上下文下的水平垂直居中 BFC的全稱是塊級排版上下文,這裏有篇文章對齊進行了簡單的介紹,BFC佈局上下文下的佈局其實就是利用盒模型本身進行的佈局,前面在利用盒模型佈局的那一節中已經講過了,這裏就不重複了 六.IFC佈局上下文下的水平垂直居中 IFC還是個什麼概念呢,你可以看看官方文檔,也可以簡單的理解爲顯示爲inline性質的行級元素的佈局。 text-align:center + vertical-align:middle 代碼:
<div class="wrap">
<div class='placeholder'><!--佔位元素,用來作爲居中元素的參照物--></div>
<div class="ele"></div>
</div>
.wrap{
width: 100%;
height: 400px;
/* min-height: 400px; */
text-align:center;
font-size: 0;
background-color: #ccc;
.placeholder,
.ele{
vertical-align: middle;
display: inline-block;
}
.placeholder{
overflow: hidden;
width: 0;
min-height: inherit;
height: inherit;
}
.ele{
width: 100px;
height: 100px;
background-color: #333;
}
}
行級元素會受到文本對齊和垂直對齊的影響,關於vertical-align,不太好理解,我多貼幾篇文章:@靈感想的,張鑫旭的,MDN上的,css-trick上的,以及官方文檔,這裏首先是用文本的中心讓內聯塊水平居中,然後給一個垂直對齊:中間,但是僅僅給垂直對齊:中間是不夠的,因爲此時它還沒有垂直對齊對齊的參照物,所以就給了一個佔位的內聯塊,它的高度是100%。 這個方法對於居中元素不需要定寬高,而且元素根據垂直對齊值的不同不僅僅可以實現居中,還可以將其放在上面下面等。缺點是父元素需定高 text-align:center + line-height DEMO鏈接 代碼:
<div class="wrap">
<div class="ele">居中居中居中居中居中居中<br>居中居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中</div>
</div>
.wrap{
text-align: center;
line-height: 400px;

width: 100%;
height: 400px;
background-color: #ccc;
font-size: 0;
.ele{
line-height: normal;
vertical-align: middle;
display: inline-block;
background-color: #333;
font-size: 18px;
color: #fff;
}
}
這個方法,首先是水平方向,文本對齊:中心就行了,至於垂直方向,起作用的就是父容器的一個行高和居中元素的垂直對齊:中,爲什麼這兩個屬性可以讓一個內聯-block垂直居中呢,這裏重點是父容器在其下面產生了一個隱匿的文本節點,這個我在上面text-align:中心+絕對那個方法的講解中說到過了,然後這個隱藏文本節點會因行高屬性的作用而擁有了一個父容器一樣高的行高,此時元素有了一個垂直對齊對齊的參照物,再給其垂直對齊:中間值就能垂直對齊了。 使用這個方法,居中元素無需定寬高,但缺點是得給父容器一個固定的行高才行。 text-align:center + font-size 代碼:
<div class="wrap">
<div class="ele"></div>
</div>
.wrap{
text-align: center;
font-size: 400px * 0.873;/*約爲高度的0.873*/

margin-left: auto;
margin-right: auto;
width: 400px;
height: 400px;
background-color: #ccc;
.ele{
vertical-align: middle;

width: 100px;
height: 100px;
display: inline-block;
background-color: #333;
}
}
這個方法來自淘寶,基本原理還是讓隱匿文本節點所佔據的行高等於父容器的高度,然後給居中元素一個垂直對齊:中間對齊的一個參照只是這裏把定義行高值換成了定義字體大小值,讓字體SIZ足夠大從而讓其行高等於父容器高度。爲了證明這個字體大小的作用,我把居中元素換成文本 代碼:
<div class="wrap">
a
</div>
.wrap{
text-align: center;
font-size: 400px * 0.873;/*約爲高度的0.873*/

margin-left: auto;
margin-right: auto;
width: 400px;
height: 400px;
background-color: #ccc;
}
效果:



可以看到字母一個垂直居中了,這個字母一個就對應那個隱匿文本節點

七.FFC佈局上下文下的水平垂直居中
父元素,子元素都定義彈性:

代碼:

<div class="wrap">
<div class="ele">
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中
</div>
</div>
html,body{
width: 100%;
height: 100%;
}

.wrap{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: #ccc;
.ele{
background-color: #333;
}
}
只有父元素定義彎曲,子元素定義保證金:自動: 代碼:
<div class="wrap">
<div class="ele">
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中<br>
居中居中居中居中居中居中居中
</div>
</div>
html,body{
width: 100%;
height: 100%;
}

.wrap{
display: flex;
width: 100%;
height: 100%;
background-color: #ccc;
.ele{
margin:auto;
background-color: #333;
}
}
flexbox的標準中有這句話(參考鏈接:http://www.w3.org/TR/css-flexbox-1/#item-margins):

相鄰柔性物品的邊緣不會崩潰。自動邊距在相應尺寸上吸收額外的空間,可用於對齊並將相鄰的柔性物品分開; 請參閱使用自動邊距對齊。

意思就是說flex項目的margin不會摺疊,在flex-item有明確大小並且margin:auto時外邊距吸收了伸縮包含塊下的額外的空間,並且能被用於居中以及會讓其相鄰的flex item儘可能的往這個flex item所在的那一個方向靠。

參考鏈接:圖CSS3 Flexbox屬性(簡體中文):Flexbox是一個非常強大的佈局模塊,

八。表佈局上下文下的水平垂直居中
代碼:

<div class='wrap'>
<div class='ele'>
<div class="ele-inner">居中居中居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中<br>居中居中居中居中居中居中居中居中居中居中</div>
</div>
</div>
.wrap{
width: 100%;
height: 300px;
display: table;
background-color: #ccc;
}
.ele{
text-align:center;
vertical-align: middle;
display:table-cell;
}

.ele-inner{
display: inline-block;
background-color: #333;
}

原理就是把DIV模擬成表格(換成真正的表格標籤也是可以的),然後給那幾個屬性就成了,這個沒什麼好講的,不懂的去翻翻手冊就明白了,然後@於江水寫的一篇表格那些事還不錯

九.CSS網布局上下文下的水平垂直居中
CSS3網格佈局是IE搞出來的一個佈局模塊,目前似似還只有IE0和IE11支持,我沒有研究過其居中的方法,有興趣的可以看看大漠老師的介紹文章

十。其它未知歸屬的水平垂直居中方法
使用按鈕標籤

代碼:

<button>
<div>
居中居中居中居中居中居中<br>
居中居中居中居中居中居中<br>
居中居中居中居中居中居中<br>
居中居中居中居中居中居中<br>
</div> 
</button>
button{
width: 100%;
height: 400px;
background-color: #cccccc;
border-width:0;
&:focus{
outline:none;
}
div{
display: inline-block;
font-size: 18px;
background-color: #333;
color: #fff;
}
}

這種方法屬於奇淫技巧,利用按鈕標籤天生外掛的這一技能對其裏面的元素進行居中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章