咱們常常用margin:0 auto來實現水平居中,而一直認爲margin:auto不能實現垂直居中……實際上,實現垂直居中僅須要聲明元素高度和下面的CSS:javascript
我不是這種實現方法的第一人,可能這只是很是常見的一種小技術,我斗膽將其命名爲絕對居中(Absolute Centering),雖然如此,可是大多數討論垂直居中的文章卻歷來不提這種方法,直到我最近瀏覽《How to Center Anything WithCSS》這篇文章的評論時候才發現這種用法。在評論列表中Simon和Priit都說起了此方法。css
若是你有任何擴展的功能或建議,能夠在此跟帖:html
CodePenjava
優勢:ide
1.支持跨瀏覽器,包括IE8-IE10.函數
2.無需其餘特殊標記,CSS代碼量少佈局
3.支持百分比%屬性值和min-/max-屬性測試
4.只用這一個類可實現任何內容塊居中
5.不管是否設置padding均可居中(在不使用box-sizing屬性的前提下)
6.內容塊能夠被重繪。
7.完美支持圖片居中。
缺點:
1.必須聲明高度(查看可變高度Variable Height)。
2.建議設置overflow:auto來防止內容越界溢出。(查看溢出Overflow)。
3.在Windows Phone設備上不起做用。
瀏覽器兼容性:
Chrome,Firefox, Safari, Mobile Safari, IE8-10.
絕對定位方法在最新版的Chrome,Firefox, Safari, Mobile Safari, IE8-10.上均測試經過。
對比表格:
絕對居中法並非惟一的實現方法,實現垂直居中還有些其餘的方法,並各有各的優點。採用哪一種技術取決於你的瀏覽器是否支持和你使用的語言標記。這個對照表有助於你根據本身的需求作出正確的選擇。
Technique |
Browser Support |
Responsive |
Overflow |
resize:both |
Variable Height |
Major Caveats |
Modern & IE8+ |
Yes |
Scroll, can overflow container |
Yes |
Yes* |
Variable Height not perfect cross-browser |
|
All |
No |
Scroll |
Resizes but doesn't stay centered |
No |
Not responsive, margins must be calculated manually |
|
Modern & IE9+ |
Yes |
Scroll, can overflow container |
Yes |
Yes |
Blurry rendering |
|
Modern & IE8+ |
Yes |
Expands container |
No |
Yes |
Extra markup |
|
Modern, IE8+ & IE7* |
Yes |
Expands container |
No |
Yes |
Requires container, hacky styles |
|
Modern & IE10+ |
Yes |
Scroll, can overflow container |
Yes |
Yes |
Requires container, vendor prefixes |
解釋:
經過以上描述,絕對居中(AbsoluteCentering)的工做機理能夠闡述以下:
一、在普通內容流(normal content flow)中,margin:auto的效果等同於margin-top:0;margin-bottom:0。
W3C中寫道If 'margin-top', or'margin-bottom' are 'auto', their used value is 0.
二、position:absolute使絕對定位塊跳出了內容流,內容流中的其他部分渲染時絕對定位部分不進行渲染。
Developer.mozilla.org:...an element that is positioned absolutely is taken out of the flow and thustakes up no space
三、爲塊區域設置top: 0; left: 0; bottom: 0; right: 0;將給瀏覽器從新分配一個邊界框,此時該塊block將填充其父元素的全部可用空間,父元素通常爲body或者聲明爲position:relative;的容器。
Developer.mozilla.org:For absolutely positioned elements, the top, right, bottom, and left propertiesspecify offsets from the edge of the element's containing block (what theelement is positioned relative to).
四、 給內容塊設置一個高度height或寬度width,可以防止內容塊佔據全部的可用空間,促使瀏覽器根據新的邊界框從新計算margin:auto
Developer.mozilla.org: The margin of the[absolutely positioned] element is then positioned inside these offsets.
五、因爲內容塊被絕對定位,脫離了正常的內容流,瀏覽器會給margin-top,margin-bottom相同的值,使元素塊在先前定義的邊界內居中。
W3.org: If none of the three [top, bottom,height] are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solvethe equation under the extra constraint that the two margins get equal values.AKA: center the block vertically
這麼看來, margin:auto彷佛生來就是爲絕對居中(Absolute Centering)設計的,因此絕對居中(Absolute Centering)應該都兼容符合標準的現代瀏覽器。
簡而言之(TL;DR):絕對定位元素不在普通內容流中渲染,所以margin:auto可使內容在經過top: 0; left: 0; bottom: 0;right: 0;設置的邊界內垂直居中。
居中方式:
內容塊的父容器設置爲position:relative,使用上述絕對居中方式,可使內容居中顯示於父容器。
如下其他的demo默認上面的CSS樣式已引用包括進去,在此基礎上只提供額外的類供用戶追加以實現不一樣的功能。
想讓內容塊一直停留在可視區域內?將內容塊設置爲position:fixed;並設置一個較大的z-index層疊屬性值。
注意:對MobileSafari,若內容塊不是放在設置爲position:relative;的父容器中,內容塊將垂直居中於整個文檔,而不是可視區域內垂直居中。
若是你要設置一個固頂的頭或增長其餘的邊欄,只須要在內容塊的樣式中加入像這樣的CSS樣式代碼:top:70px;bottom:auto;因爲已經聲明瞭margin:auto;,該內容塊將會垂直居中於你經過top,left,bottom和right屬性定義的邊界框內。
你能夠將內容塊固定與屏幕的左側或右側,而且保持內容塊垂直居中。使用right:0;left:auto;固定於屏幕右側,使用left:0;right:auto;固定與屏幕左側。
絕對居中最大的優點應該就是對百分比形式的寬高支持的很是完美。甚至min-width/max-width 和min-height/max-height這些屬性在自適應盒子內的表現也和預期很一致。
給內容塊元素加上padding也不影響內容塊元素的絕對居中實現。
內容高度大於塊元素或容器(視區viewport或設爲position:relative的父容器)會溢出,這時內容可能會顯示到塊與容器的外面,或者被截斷出現顯示不全(分別對應內容塊overflow屬性設置爲visible和hidden的表現)。
加上overflow: auto會在內容高度超過容器高度的狀況下給內容塊顯示滾動條而不越界。
若是內容塊自身不設置任何padding的話,能夠設置max-height: 100%;來保證內容高度不超越容器高度。
你可使用其餘class類或javascript代碼來重繪內容塊同時保證居中,無須手動從新計算中心尺寸。固然,你也能夠添加resize屬性來讓用戶拖拽實現內容塊的重繪。
絕對居中(Absolute Centering)能夠保證內容塊始終居中,不管內容塊是否重繪。能夠經過設置min-/max-來根據本身須要限制內容塊的大小,並防止內容溢出窗口/容器。
若是不使用resize:both屬性,可使用CSS3動畫屬性transition來實現重繪的窗口之間平滑的過渡。必定要設置overflow:auto;以防重繪的內容塊尺寸小於內容的實際尺寸這種狀況出現。
絕對居中(AbsoluteCentering)是惟一支持resize:both屬性實現垂直居中的技術。
注意:
絕對居中(AbsoluteCentering)也適用於圖片。對圖片自身應用class類或CSS樣式,並給圖片添加height:auto樣式,圖片會自適應居中顯示,若是外層容器能夠resize則隨着容器的重繪,圖片也相應重繪,始終保持居中。
須要注意的是height:auto雖然對圖片居中有用,但若是是在圖片外層的內容塊上應用了height:auto則會產生一些問題:規則的內容塊會被拉伸填充整個容器。這時,咱們可使用可變高度(Variable Height)方式解決這個問題。問題的緣由多是渲染圖片時要計算圖片高度,這就如同你本身定義了圖片高度同樣,瀏覽器獲得了圖片高度就不會像其餘狀況同樣去解析margin:auto垂直居中了。因此咱們最好對圖片自身應用這些樣式而不是父元素。
HTML:
CSS:
.Absolute-Center.is-Image {
height: auto;
}
.Absolute-Center.is-Image img {
width: 100%;
height: auto;
}
最好是對圖片自身應用此方法,效果以下圖:
這種狀況下實現絕對居中(AbsoluteCentering)必需要聲明一個高度,無論你是基於百分比的高度仍是經過max-height控制的高度,還有,別忘了設置合適的overflow屬性。對自適應/響應式情景,這種方法很不錯。
與聲明高度效果相同的另外一種方法是設置display:table;這樣不管實際內容有多高,內容塊都會保持居中。這種方法在一些瀏覽器(如IE/FireFox)上會有問題,個人搭檔Kalley
在ELL Creative(訪問ellcreative.com )上寫了一個基於Modernizr插件的檢測函數,用來檢測瀏覽器是否支持這種居中方法,進一步加強用戶體驗。
Javascript:
/* Modernizr Test for Variable Height Content */ Modernizr.testStyles('#modernizr { display: table; height: 50px; width: 50px; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; }', function(elem, rule) { Modernizr.addTest('absolutecentercontent', Math.round(window.innerHeight / 2 - 25) === elem.offsetTop); });
CSS:
.absolutecentercontent .Absolute-Center.is-Variable { display: table; height: auto; }
缺點:
瀏覽器兼容性不太好,若Modernizr不能知足你的需求,你須要尋找其餘方法解決。
1. 與上述重繪(Resizing)狀況的方法不兼容
2. Firefox/IE8:使用display:table會使內容塊垂直居上,不過水平仍是居中的。
3. IE9/10: 使用display:table會使內容塊顯示在容器左上角。
4. Mobile Safari:內容塊垂直居中;若使用百分比寬度,水平方向居中會稍微偏離中心位置。
絕對居中(Absolute Centering)是一種很是不錯的技術,除此以外還有一些方法能夠知足更多的具體需求,最多見的推薦:NegativeMargins, Transforms,Table-Cell, Inline-Block方式和新出現的Flexbox.方式。這些方法許多文章都有深刻講解,這裏只作簡單闡述。
這或許是當前最流行的使用方法。若是塊元素尺寸已知,能夠經過如下方式讓內容塊居中於容器顯示:
外邊距margin取負數,大小爲width/height(不使用box-sizing: border-box時包括padding,)的一半,再加上top: 50%; left: 50%;。即:
.is-Negative {
width: 300px;
height: 200px;
padding: 20px;
position: absolute;
top: 50%; left: 50%;
margin-left: -170px; /* (width + padding)/2 */
margin-top: -120px; /* (height + padding)/2 */
}
測試代表,這是惟一在IE6-IE7上也表現良好的方法。
優勢:
1. 良好的跨瀏覽器特性,兼容IE6-IE7。
2. 代碼量少。
缺點:
1. 不能自適應。不支持百分比尺寸和min-/max-屬性設置。
2. 內容可能溢出容器。
3. 邊距大小與padding,和是否認義box-sizing: border-box有關,計算須要根據不一樣狀況。
這是最簡單的方法,不近能實現絕對居中一樣的效果,也支持聯合可變高度方式使用。內容塊定義transform: translate(-50%,-50%)必須帶上瀏覽器廠商的前綴,還要加上
top: 50%; left: 50%;
代碼類:
.is-Transformed {
width: 50%;
margin: auto;
position: absolute;
top: 50%; left: 50%;
-webkit-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
}
優勢:
1. 內容可變高度
2. 代碼量少
缺點:
1. IE8不支持
2. 屬性須要寫瀏覽器廠商前綴
3. 可能干擾其餘transform效果
4. 某些情形下會出現文本或元素邊界渲染模糊的現象
進一步瞭解transform實現居中的知識能夠參考CSS-Tricks的文章《Centering PercentageWidth/Height Elements》
總的說來這多是最好的居中實現方法,由於內容塊高度會隨着實際內容的高度變化,瀏覽器對此的兼容性也好。最大的缺點是須要大量額外的標記,須要三層元素讓最內層的元素居中。
HTML:
<div class="Center-Container is-Table"> <div class="Table-Cell"> <div class="Center-Block"> <!-- CONTENT --> </div> </div> </div>
CSS:
.Center-Container.is-Table { display: table; }
.is-Table .Table-Cell {
display: table-cell;
vertical-align: middle;
}
.is-Table .Center-Block {
width: 50%;
margin: 0 auto;
}
優勢:
1. 高度可變
2. 內容溢出會將父元素撐開。
3. 跨瀏覽器兼容性好。
缺點:
須要額外html標記
瞭解更多表格單元格實現居中的知識,請參考Roger Johansson發表在456bereastreet的文章《Flexibleheight vertical centering with CSS, beyond IE7》
很受歡迎的一種居中實現方式,基本思想是使用display: inline-block, vertical-align: middle和一個僞元素讓內容塊處於容器中央。這個概念的解釋能夠參考CSS-Tricks上的文章《Centering in the Unknown》
我這個例子也有一些其餘地方見不到的小技巧,有助於解決一些小問題。
若是內容塊寬度大於容器寬度,好比放了一個很長的文本,但內容塊寬度設置最大不能超過容器的100%減去0.25em,不然使用僞元素:after內容塊會被擠到容器頂部,使用:before內容塊會向下偏移100%。
若是你的內容塊須要佔據儘量多的水平空間,可使用max-width: 99%;(針對較大的容器)或max-width: calc(100% -0.25em)(取決於支持的瀏覽器和容器寬度)。
HTML:
<div class="Center-Container is-Inline"> <div class="Center-Block"> <!-- CONTENT --> </div> </div>
CSS:
.Center-Container.is-Inline {
text-align: center;
overflow: auto;
}
.Center-Container.is-Inline:after,
.is-Inline .Center-Block {
display: inline-block;
vertical-align: middle;
}
.Center-Container.is-Inline:after {
content: '';
height: 100%;
margin-left: -0.25em; /* To offset spacing. May vary by font */
}
.is-Inline .Center-Block {
max-width: 99%; /* Prevents issues with long content causes the content block to be pushed to the top */
/* max-width: calc(100% - 0.25em) /* Only for IE9+ */
}
這種方法的優劣和單元格Table-Cell方式差很少,起初我把這種方式忽略掉了,由於這確實是一種hack方法。不過,不管如何,這是很流行的一種用法,瀏覽器支持的也很好。
優勢:
1. 高度可變
2. 內容溢出會將父元素撐開。
3. 支持跨瀏覽器,也適應於IE7。
缺點:
1.須要一個容器
2.水平居中依賴於margin-left: -0.25em;該尺寸對於不一樣的字體/字號須要調整。
3.內容塊寬度不能超過容器的100% - 0.25em。
更多相關知識參考ChrisCoyier的文章《Centeringin the Unknown》
這是CSS佈局將來的趨勢。Flexbox是CSS3新增屬性,設計初衷是爲了解決像垂直居中這樣的常見佈局問題。相關的文章如《Centering Elements with Flexbox》
記住Flexbox不僅是用於居中,也能夠分欄或者解決一些使人抓狂的佈局問題。
優勢:
1.內容塊的寬高任意,優雅的溢出。
2.可用於更復雜高級的佈局技術中。
缺點:
1. IE8/IE9不支持。
2. Body須要特定的容器和CSS樣式。
3. 運行於現代瀏覽器上的代碼須要瀏覽器廠商前綴。
4. 表現上可能會有一些問題
有關Flexbox Centering的文章能夠參考David Storey的文章《Designing CSS Layouts WithFlexbox Is As Easy As Pie》
建議:
每種技術都有其優劣之處。你選擇哪種技術取決於支持的瀏覽器和你的編碼。使用上面的對照表有助於你作出決定。
做爲一種簡單的替代方案,絕對居中(Absolute Centering)技術表現良好。曾經你使用負邊距(Negative Margins)的地方,如今能夠用絕對居中(Absolute Centering)替代了。你再也不須要處理討厭的邊距計算和額外的標記,並且還能讓內容塊自適應大小居中。
若是你的站點須要可變高度的內容,能夠試試單元格(Table-Cell)和行內塊元素(Inline-Block)這兩種方法。若是你處在流血的邊緣,試試Flexbox,體驗一下這一高級佈局技術的好處吧。
轉自http://blog.csdn.net/freshlover/article/details/11579669