盤點8種css實現垂直水平居中

1.絕對定位居中技術

我們一直用margin:auto實現水平居中,而一直認為margin:auto不能實現垂直居中,實際上可以通過聲明元素的高度和下面的css

.Absolute-Center {
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}

優點:
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設備上不起作用。

解釋

1、在普通內容流(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.
2、position:absolute使絕對定位塊跳出了內容流,內容流中的其余部分渲染時絕對定位部分不進行渲染。
Developer.mozilla.org:...an element that is positioned absolutely is taken out of the flow and thustakes up no space
3、為塊區域設置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).
4、 給內容塊設置一個高度height或寬度width,能夠防止內容塊占據所有的可用空間,促使瀏覽器根據新的邊界框重新計算margin:auto
Developer.mozilla.org: The margin of the[absolutely positioned] element is then positioned inside these offsets.
5、由于內容塊被絕對定位,脫離了正常的內容流,瀏覽器會給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;設置的邊界內垂直居中。

居中方式

1.容器內
內容塊的父容器設置為position:relative,使用上述絕對居中方式,可以使內容居中顯示于父容器。

.Center-Container {
position: relative;
}
.Absolute-Center {
width: 50%;
height: 50%;
overflow: auto;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}

Paste_Image.png

2.視區內
想讓內容塊一直停留在可視區域內?將內容塊設置為position:fixed;并設置一個較大的z-index層疊屬性值。

.Absolute-Center.is-Fixed {
position: fixed;
z-index: 999;
}

image

3.邊欄
如果你要設置一個固頂的頭或增加其他的邊欄,只需要在內容塊的樣式中加入像這樣的CSS樣式代碼:top:70px;bottom:auto;由于已經聲明了margin:auto;,該內容塊將會垂直居中于你通過top,left,bottom和right屬性定義的邊界框內。

你可以將內容塊固定與屏幕的左側或右側,并且保持內容塊垂直居中。使用right:0;left:auto;固定于屏幕右側,使用left:0;right:auto;固定與屏幕左側

.Absolute-Center.is-Right {
left: auto; right: 20px;
text-align: right;
}
.Absolute-Center.is-Left {
right: auto; left: 20px;
text-align: left;
}

Paste_Image.png

4.響應式/自適應居中
絕對居中最大的優勢應該就是對百分比形式的寬高支持的非常完美。甚至min-width/max-width 和min-height/max-height這些屬性在自適應盒子內的表現也和預期很一致。

Paste_Image.png

.Absolute-Center.is-Responsive {
width: 60%;
height: 60%;
min-width: 200px;
max-width: 400px;
padding: 40px;
}

5.溢出情況
內容高度大于塊元素或容器(視區viewport或設為position:relative的父容器)會溢出,這時內容可能會顯示到塊與容器的外面,或者被截斷出現顯示不全(分別對應內容塊overflow屬性設置為visible和hidden的表現)。
加上overflow: auto會在內容高度超過容器高度的情況下給內容塊顯示滾動條而不越界。

.Absolute-Center.is-Overflow {
overflow: auto;
}

Paste_Image.png

6.重繪
你可以使用其他class類或JavaScript代碼來重繪內容塊同時保證居中,無須手動重新計算中心尺寸。當然,你也可以添加resize屬性來讓用戶拖拽實現內容塊的重繪。
絕對居中(Absolute Centering)可以保證內容塊始終居中,無論內容塊是否重繪。可以通過設置min-/max-來根據自己需要限制內容塊的大小,并防止內容溢出窗口/容器。

.Absolute-Center.is-Resizable {
min-width: 20%;
max-width: 80%;
min-height: 20%;
max-height: 80%;
resize: both;
overflow: auto;
}

Paste_Image.png

如果不使用resize:both屬性,可以使用CSS3動畫屬性transition來實現重繪的窗口之間平滑的過渡。一定要設置overflow:auto;以防重繪的內容塊尺寸小于內容的實際尺寸這種情況出現。
絕對居中(AbsoluteCentering)是唯一支持resize:both屬性實現垂直居中的技術。

注意:

要設置max-width/max-height屬性來彌補內容塊padding,否則可能溢出。
手機瀏覽器和IE8-IE10瀏覽器不支持resize屬性,所以如果對你來說,這部分用戶體驗很必要,務必保證對resizing你的用戶有可行的退路。
聯合使用resize 和 transition屬性會在用戶重繪時,產生一個transition動畫延遲時間。
7.圖片
絕對居中(AbsoluteCentering)也適用于圖片。對圖片自身應用class類或CSS樣式,并給圖片添加height:auto樣式,圖片會自適應居中顯示,如果外層容器可以resize則隨著容器的重繪,圖片也相應重繪,始終保持居中。

需要注意的是height:auto雖然對圖片居中有用,但如果是在圖片外層的內容塊上應用了height:auto則會產生一些問題:規則的內容塊會被拉伸填充整個容器。這時,我們可以使用可變高度(Variable Height)方式解決這個問題。問題的原因可能是渲染圖片時要計算圖片高度,這就如同你自己定義了圖片高度一樣,瀏覽器得到了圖片高度就不會像其他情況一樣去解析margin:auto垂直居中了。所以我們最好對圖片自身應用這些樣式而不是父元素。

Paste_Image.png
Paste_Image.png

.Absolute-Center.is-Image {
height: auto;
}

.Absolute-Center.is-Image img {
width: 100%;
height: auto;
}
最好是對圖片自身應用此方法

Paste_Image.png

8.可變高度
這種情況下實現絕對居中(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;
}

Paste_Image.png

9.負外邊距
這或許是當前最流行的使用方法。如果塊元素尺寸已知,可以通過以下方式讓內容塊居中于容器顯示:

外邊距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 */
}

Paste_Image.png

10.變形
這是最簡單的方法,不近能實現絕對居中同樣的效果,也支持聯合可變高度方式使用。內容塊定義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%);
}

Paste_Image.png

優點:內容可邊度高,代碼量少

11.表格單元格
總的來說這可能是最好的實現居中的方法,因為內容塊高度會隨著實際內容的高度變化,最大的去缺點是需要大量額外的標記,需要三層元素讓最內層元素居中

html:
<div class="Center-Container is-Table">
<div class="Table-Cell">
<div class="Center-Block">

</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;
}

Paste_Image.png

12.行內塊元素
很受歡迎的一種居中實現方式,基本思想是使用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">

</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+ */
}

Paste_Image.png

十三、Flexbox

這是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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,774評論 1 92
  • 收聽音頻,戳鏈接,舊號itclan已暫停使用,歡迎關注微信itclanCoder公眾號可收聽更多音頻 前言 關于網...
    itclanCoder閱讀 8,196評論 3 30
  • 各種純css圖標 CSS3可以實現很多漂亮的圖形,我收集了32種圖形,在下面列出。直接用CSS3畫出這些圖形,要比...
    劍殘閱讀 9,607評論 0 8
  • div水平居中的N種方法 一、單行垂直居中 如果一個容器中只有一行文字,對它實現居中相對比較簡單,我們只需要設置它...
    fredah閱讀 5,940評論 0 1
  • 回家葛優躺,然后11點精神得很,可我知道,這樣的身體不好,我不要于是今天一直努力克服讓自己,回到家,第一件事要洗澡...
    紫色風鈴yy閱讀 121評論 0 0