咱們都知道 margin:0 auto;
的樣式能讓元素水平居中,而 margin: auto;
卻不能作到垂直居中……直到如今。可是,請注意!想讓元素絕對居中,只須要聲明元素高度,而且附加如下樣式,就能夠作到:css
1
2
3
4
5
|
.Absolute-Center {
margin
:
auto
;
position
:
absolute
;
top
:
0
;
left
:
0
;
bottom
:
0
;
right
:
0
;
}
|
我並非第一個發現這種方法的人(不過我仍是敢把它叫作「徹底居中」),它有多是種很是廣泛的技巧。但大多數介紹垂直居中的文章中並無提到過這種方法。若是不是瀏覽這篇文章的評論,我甚至根本就不會發現這個辦法。html
上面那篇文章的評論欄中,Simon提供了一個jsFiddle的連接,其餘的方法相比之下就相形見絀了。(Priit也在評論欄中提到了一樣的方法)。深刻研究了一番以後,我又用某些關鍵詞找到了記載這種方法的三個網站:站點一、站點二、站點三。web
之前從未用過這種方法的我想試試,看看這種」徹底居中」的方法到底有多麼神奇。 好處:瀏覽器
同時注意:ide
瀏覽器支持:Chrome、Firefox、Safari、Mobile Safari、IE8-10。 「徹底居中」經測試能夠完美地應用在最新版本的Chrome、Firefox、Safari、Mobile Safari中,甚至也能夠運行在IE8~IE10上佈局
「徹底居中」並非本篇文章中惟一的選項。要作到垂直居中,還存在着其餘方法,各有各的長處。採起什麼樣的方法,取決於你所支持的瀏覽器,以及現有標籤的結構。下面這張對照表可以幫你選出最符合你須要的方法。性能
所用樣式測試 |
支持的瀏覽器字體 |
是否 響應式flex |
內容溢出後的樣式 |
resize:both |
高度可變 |
主要缺陷 |
Absolute |
現代瀏覽器&IE8+ |
是 |
會致使容器溢出 |
是 |
是* |
‘可變高度’的特性不能跨瀏覽器 |
負margin值 |
全部 |
否 |
帶滾動條 |
大小改變後再也不居中 |
否 |
不具備響應式特性,margin值必須通過手工計算 |
Transform |
現代瀏覽器&IE9+ |
是 |
會致使容器溢出 |
是 |
是 |
妨礙渲染 |
Table-Cell |
現代瀏覽器&IE8+ |
是 |
撐開容器 |
否 |
是 |
會加上多餘的標記 |
Inline-Block |
現代瀏覽器&IE8+&IE7* |
是 |
撐開容器 |
否 |
是 |
須要使用容器包裹和hack式的樣式 |
Flexbox |
現代瀏覽器&IE10+ |
是 |
會致使容器溢出 |
是 |
是 |
須要使用容器包裹和廠商前綴(vendor prefix) |
在研究了規範和文檔後,我總結出了「徹底居中」的工做原理:
W3.org 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 thus takes up no space
3. 設置了top: 0; left: 0; bottom: 0; right: 0; 樣式的塊元素會讓瀏覽器爲它包裹一層新的盒子,所以這個元素會填滿它相對父元素的內部空間,這個相對父元素能夠是是body標籤,或者是一個設置了position: relative; 樣式的容器。 Developer.mozilla.org For absolutely positioned elements, the top, right, bottom, and left properties specify offsets from the edge of the element’s containing block (what the element is positioned relative to).
4. 給元素設置了寬高之後,瀏覽器會阻止元素填滿全部的空間,根據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’, solve the equation under the extra constraint that the two margins get equal values.?AKA: center the block vertically
使用「徹底居中」,有意遵守了標準margin: auto; 樣式渲染的規定,因此應當在與標準兼容的各類瀏覽器中起做用。
使用「徹底居中」,就能夠在一個設置了position: relative的容器中作到徹底居中元素了! (居中例子,請前往英文原文查看)
1
2
3
4
5
6
7
8
9
10
11
12
|
.Center-Container {
position
:
relative
;
}
.Absolute-Center {
width
:
50%
;
height
:
50%
;
overflow
:
auto
;
margin
:
auto
;
position
:
absolute
;
top
:
0
;
left
:
0
;
bottom
:
0
;
right
:
0
;
}
|
接下來的示例會假設已經包含了如下樣式,而且以逐步添加樣式的方式提供不一樣的特性。
想要使內容區在可視區域內居中麼?設置position: fixed樣式,並設置一個較高的z-index值,就能夠作到。
1
2
3
4
|
.Absolute-Center.is-Fixed {
position
:
fixed
;
z-index
:
999
;
}
|
移動版Safari的說明:若是外面沒有一層設置position: relative的容器,內容區會以整個文檔的高度的中心點爲基準居中,而不是以可視區域的高度中心點爲基準居中。
若是須要添加固定的標題,或者其餘帶偏移樣式的元素,能夠直接把相似top: 70px; 的樣式寫進內容區域的樣式中。一旦聲明瞭margin: auto; 的樣式,內容塊的top
left
bottom
right
的屬性值也會同時計算進去。
若是想讓內容塊在貼近側邊的過程當中保持水平居中,可使用right: 0; left: auto; 讓內容貼在右側,或者使用left: 0; right: auto; 使內容貼在左側。
1
2
3
4
|
.Absolute-Center.is-Fixed {
position
:
fixed
;
z-index
:
999
;
}
|
使用absolute的最大好處就是能夠完美地使用帶百分比的寬高樣式!就算是min-width/max-width或者min-height/max-height也可以有如預期般的表現。
再進一步加上padding樣式的話,absolute式的徹底居中也絲絕不會破壞!
1
2
3
4
5
6
7
|
.Absolute-Center.is-Responsive {
width
:
60%
;
height
:
60%
;
min-width
:
200px
;
max-width
:
400px
;
padding
:
40px
;
}
|
內容區高度大於可視區域或者一個position: relative的容器,其內容可能會溢出容器,或被容器截斷。只要內容區域沒有超出容器(沒有給內容容器預留padding的話,能夠設置max-height: 100%;的樣式),那麼容器內就會產生滾動條。
1
2
3
|
.Absolute-Center.is-Overflow {
overflow
:
auto
;
}
|
使用其餘樣式,或者使用JavaScript調整內容區的大小,也是不用手動從新計算的!若是設置了resize的樣式,甚至可讓用戶自行調節內容區域的大小。 「徹底居中」法,不管內容區怎麼改變大小,都會保持居中。
設置了min-/max- 開頭的屬性能夠限制區塊的大小而不用擔憂撐開容器。
1
2
3
4
5
6
7
8
|
.Absolute-Center.is-Resizable {
min-width
:
20%
;
max-width
:
80%
;
min-height
:
20%
;
max-height
:
80%
;
resize:
both
;
overflow
:
auto
;
}
|
若是不設置resize: both的樣式,能夠設置transition樣式平滑地在大小間切換。必定要記得設置overflow: auto樣式,由於改變大小後的容器高寬頗有可能會小於內容的高寬。 「徹底居中」法是惟一一種能支持使用resize: both樣式的方法。
使用注意:
圖像也一樣有效!提供相應的class,並指定樣式 height: auto; ,就獲得了一張隨着容器改變大小的響應式圖片。
請注意,height: auto; 樣式雖然對圖片有效,若是沒有用到了後面介紹的‘可變高技巧’,則會致使普通內容區域伸長以適應容器長度。
瀏覽器頗有多是根據渲染結果填充了圖像高度值,因此在測試過的瀏覽器中,margin: auto; 樣式就像是聲明瞭固定的高度值通常正常工做。
HTML:
1
|
<
img
src
=
"http://placekitten.com/g/500/200"
alt
=
""
/>
|
CSS:
1
2
3
4
5
6
7
8
|
.Absolute-Center.is-Image {
height
:
auto
;
}
.Absolute-Center.is-Image img {
width
:
100%
;
height
:
auto
;
}
|
「徹底居中」法的確須要聲明容器高度,可是高度受max-height樣式的影響,也能夠是百分比。這很是適合響應式的方案,只須要設置好帶溢出內容就行。
另外一種替代方案是設置display: table樣式居中,,無論內容的長度。這種方法會在一些瀏覽器中產生問題(主要是IE和Firefox)。我在ELL Creative的朋友Kalley寫了一個基於Modernizr 的測試,能夠用來檢查瀏覽器是否支持這種居中方案。如今這種方法能夠作到漸進加強。
注意要點: 這種方法會破壞瀏覽器兼容性,若是Modernizr測試不能知足你的需求,你可能須要考慮其餘的實現方案。
Javascript:
1
2
3
4
|
/* 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:
1
2
3
4
|
.absolutecentercontent .Absolute-Center.is-Variable {
display
: table;
height
:
auto
;
}
|
「徹底居中」法是解決居中問題的好方法,同時也有許多能夠知足不一樣需求的其餘方法。最多見的,推薦的方法有負margin值、transform法、table-cell法、inline-block法、以及如今出現的Flexbox法,這些方法其餘文章都有深刻介紹,因此這裏只會稍稍說起。
這或許是最經常使用的方法。若是知道了各個元素的大小,設置等於寬高一半大小的負margin值(若是沒有使用box-sizing: border-box樣式,還須要加上padding值),再配合top: 50%; left: 50%;樣式就會使塊元素居中。
須要注意的是,這是按照預想狀況也能在工做在IE6-7下的惟一方法。
1
2
3
4
5
6
7
8
9
|
.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 */
}
|
好處:
同時注意:
和「徹底居中」法的好處同樣,簡單有效,同時支持可變高度。爲內容指定帶有廠商前綴的transform: translate(-50%,-50%)和top: 50%; left: 50%;樣式就可讓內容塊居中。
1
2
3
4
5
6
7
8
9
|
.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%
);
}
|
好處:
同時注意:
這種多是最好的方法,由於高度能夠隨內容改變,瀏覽器支持也不差。主要缺陷是會產生額外的標籤,每個須要居中的元素須要三個額外的HTML標籤。
HTML:
1
2
3
4
5
6
7
|
<div class=
"Center-Container is-Table"
>
<div class=
"Table-Cell"
>
<div class=
"Center-Block"
>
<!-- CONTENT -->
</div>
</div>
</div>
|
CSS:
1
2
3
4
5
6
7
8
9
|
.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
;
}
|
好處:
同時注意:
迫切須要的方法:inline-block法居中。基本方法是使用 display: inline-block
, vertical-align: middle
樣式和僞元素讓內容塊在容器中居中。個人實現用到了幾個在其餘地方見不到的新技巧解決了一些問題。
內容區聲明的寬度不能大於容器的100% 減去0.25em的寬度。就像一段帶有長文本的區域。否則,內容區域會被推到頂端,這就是使用:after僞類的緣由。使用:before僞類則會讓元素有100%的大小!
若是內容塊須要儘量大地佔用水平空間,能夠爲大容器加上max-width: 99%;樣式,或者考慮瀏覽器和容器寬度的狀況下使用max-width: calc(100% – 0.25em) 樣式。
這種方法和table-cell的大多數好處相同,不過最初我放棄了這個方法,由於它更像是hack。無論這一點的話,瀏覽器支持很不錯,並且也被證明是很流行的方法。
HTML:
1
2
3
4
5
|
<
div
class
=
"Center-Container is-Inline"
>
<
div
class
=
"Center-Block"
>
<!-- CONTENT -->
</
div
>
</
div
>
|
CSS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
.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+ */
}
|
好處:
同時注意:
CSS將來發展的方向就是採用Flexbox這種設計,解決像垂直居中這種共同的問題。請注意,Flexbox有不止一種辦法居中,他也能夠用來分欄,並解決奇奇怪怪的佈局問題。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
.Center-Container.is-Flexbox {
display
: -webkit-box;
display
: -moz-box;
display
: -ms-flexbox;
display
: -webkit-flex;
display
: flex;
-webkit-box-align:
center
;
-moz-box-align:
center
;
-ms-flex-align:
center
;
-webkit-align-items:
center
;
align-items:
center
;
-webkit-box-pack:
center
;
-moz-box-pack:
center
;
-ms-flex-pack:
center
;
-webkit-justify-
content
:
center
;
justify-
content
:
center
;
}
|
好處:
同時注意: 不支持IE8-9
各項技術都有各自的好處,採起什麼樣的方法,取決於你所支持的瀏覽器,以及現有標籤的結構。請使用上面提供對照表幫你選出最符合你須要的方法。
「徹底居中」法簡單方便,迅速及時。之前使用負Margin值的地方,均可以使用Absolute居中。無需繁瑣的數學計算,無需額外標籤,並且能夠隨時改變大小。
若是網站須要可變高度的內容,並且同時照顧到瀏覽器兼容性的話,能夠嘗試table-cell和inline-block技術,若是想嘗試新鮮事物的話,可使用Flexbox,並享受這種高級技術帶來的好處。