Reference: http://blog.yam.com/hanasan/article/35806444 & http://blog.yam.com/hanasan/article/85889063
---------------------------------------------------------------------------------------------------------------------------------
方法一
使用CSS table-cell屬性來完成,什麼是table-cell?簡單說就是針對一些html object附于它table的屬性(詳見此),如果曾經使用過table來排版的網頁開發者,應該知道td的既有屬性valign,古早以前根本不會有垂直置中的問題,因為td下個valign="middle"就行了。 而table-cell即是可以將div模擬成表格(table)的儲存格(td),讓原本不存在vertical-align的div可以使用。
Sample Code
HTML
<div id="wrap"> <div id="cell"> <div id="content"> 要被置中的內容 </div> </div> </div>
CSS
#wrap { display:table; } #cell { display:table-cell; vertical-align:middle; }
優點:
- 因為是CSS2.1釋出的標準屬性,正規的解決方法。
- 被置中的內容增加後,垂直置中的block會自動調整。
缺點:
- 支援性不佳,IE8以上才支援(IE7以下不支援display:table語法)
- 太多巢狀標籤(有種回到過去table排版的fu)
方法二
此方法適用在定義了絕對定位(absolute)的div, 將其top設置為50%, 再設置與div高度一半的「負」值margin-top,意謂著使用本方法必須固定div的高度。
Sample Code
HTML
<div id="center"> 要被置中的內容 </div>
CSS
#center { position:absolute; height:400px; top:50%; margin-top:-200px; /* div高度的一半 */ }
優點:
- 程式碼簡短,且無需為了「垂直置中」的目的多寫巢狀標籤
- 所有browser都支援,泛用性高
缺點:
- div高度需固定,若是動態資料有可能超過的話需要加上overflow:scroll讓溢出的內容可以看見
方法三
在需要被垂直置中的div前放置另一個div,設置為height:50%,margin-bottom:-contentHeight(目標高度的負值)
Sample Code
HTML
<body> <div id="floater"></div> <div id="middle"> 要被置中的div </div> </body>
CSS
html, body { margin:0; padding:0; height:100%; } #floater { float:left; height:50%; margin-bottom:-200px; width:1px; /* only for IE7 */ } #middle { clear:both; height:400px; position:relative; }
優點:
- 所有browser都支援(Note:IE7必須在#floater追加width:1px才work!)
- 當內容增加時,垂直置中的div不會被切掉,而是會自動出現scroll-bar
缺點:
- 沒甚麼缺點,真要說就是一樣高度得固定。另外若置中物件的父層是body, 即使視窗被USER拖曳拉小了,div也一樣會唯持置中(笑)
方法四
本法使用在同樣是絕對定位(absolute)的div上,固定高度,並定義top:0; bottom:0; 和廣為被應用的
{ margin:0 auto; }作div水平置中原理類似
Sample Code
HTML
<div id="middle"> 我要被置中啦~ </div>
CSS
#middle { position:absolute; width:70%; height:280px; top:0; bottom:0; left:0; right:0; margin:auto; }
優點:
- 簡單
缺點:
- 不支援IE7(含)以下
- 如果容器不夠裝內文, 也不會有scrollbar自動出現...
方法五
此方法適用於「單行」文字的垂直置中(EX:要作英文網站大Slogan時), container除了設置高度之外,同時也將行距(line-height)設置與高度相等。
Sample Code
HTML
<div id="content"> 一行文字要被置中啦 </div>
CSS
#content { font-size:32px; text-align:center; height:150px; line-height:150px; }
優點:
- 簡單
- 所有browser都支援(even IE6!)
- 即使內容溢出也不會被切掉
缺點:
- 只有單行文字適合
- 若div寬度固定,一當有長文字爆行時會很醜,務必小心使用。
方法A - :before pseudo element 偽元素的運用
先聲明!這個方法已流傳一陣子,但好 Code 就是要分享出去,讓更多為了 div 垂直置中問題煩惱的人可以順利解決 :D
HTML
1
2
3
|
< div class = "wrapper" > < div class = "center" ></ div > </ div > |
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
.wrapper { height : 250px ; background-color : #9096A6 ; text-align : center ; } .wrapper:before { content : "" ; height : 100% ; display : inline- block ; vertical-align : middle ; } . center { display : inline- block ; vertical-align : middle ; width : 180px ; height : 120px ; } |
Demo
.wrapper
的部分也可以用最頂層的 body
取代,如此一來,.center
就會在整個畫面垂直置中了。
而它的原理其實也不難理解,就是「利用偽元素」在外框裡面塞入一個和外框等高的 inline-block 行內元素,它是不被看到的,如此一來,在外框裡面的其它高度沒有100%的行內元素也可以遵循 vertical-align: middle 的方法去排隊了。用一張圖來解釋的話就是這樣↓
優點
很簡單,效果卻出奇地好
缺點
沒有明顯的缺點,除非你想「垂直置中」的元素是複數,在水平想要做 float left or right 則無法兩者兼顧
沒有固定高度,即高度不確定的多行內容是否也能垂直置中?
令人驚訝的是,這個方法居然也是可行的!只要做一點小修改,將外層加上 font-size: 0;
,並將原本的 .center
的高度值拿掉,dom元素由 div 換成 p 即可,但是要記得將目標的 font-size
給加回來,否則文字就看不見了,理由是 font-size 會繼承。
HTML
1
2
3
|
< div class = "wrapper" > < p class = "text" >Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus suscipit explicabo unde sit atque exercitationem delectus qui ipsam, at. Vitae veritatis officia quidem commodi repudiandae illum cum, quisquam voluptatibus quaerat.</ p > </ div > |
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
.wrapper { height : 250px ; background-color : #9096A6 ; text-align : center ; /* Point */ font-size : 0 ; } .wrapper:before { content : "" ; height : 100% ; display : inline- block ; vertical-align : middle ; } p.text{ display : inline- block ; vertical-align : middle ; /* Point 要使用絕對值的 font-size 覆寫掉父層的 font-size: 0 */ font-size : 15px ; } |
Demo
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus suscipit explicabo unde sit atque exercitationem delectus qui ipsam, at. Vitae veritatis officia quidem commodi repudiandae illum cum, quisquam voluptatibus quaerat.
Nam maiores nulla voluptas nostrum quibusdam! Laboriosam dignissimos debitis provident ad et in facere voluptas, voluptate delectus ullam optio numquam soluta eligendi beatae vero quasi amet magnam. Facilis inventore cupiditate ducimus voluptatum dicta quam fugit totam placeat iste rem in quisquam sint deserunt accusamus natus necessitatibus velit, aut voluptatibus quae consectetur beatae nam vel officia ex. Distinctio quae totam dolor laudantium pariatur, explicabo unde voluptatibus voluptates, est quia doloremque quas nam. Natus modi odio, dolor cumque nam voluptate harum commodi hic, numquam saepe perferendis necessitatibus ducimus, cum quo rem sunt enim et impedit non dolorem. Animi quidem ipsam quaerat ea, saepe officiis impedit praesentium rerum! Dolor, aut iste aliquid voluptatibus nulla. Tenetur fuga, in eaque architecto vel natus laborum ducimus.
延伸題:「如果是有二段以上的文字,也可以整體都 垂直置中 嗎?」
HTML
1
2
3
4
5
6
7
|
< div class = "wrapper" > < div class = "text" > < p >Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque, in.</ p > < p >Modi excepturi voluptatibus expedita voluptas laborum veritatis error adipisci doloremque. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid cum asperiores dicta, magnam quibusdam veniam nemo aperiam sit quas fugiat?</ p > < p >Modi excepturi voluptatibus expedita voluptas laborum veritatis error adipisci doloremque. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid cum asperiores dicta, magnam quibusdam veniam nemo aperiam sit quas fugiat?</ p > </ div > </ div > |
Demo
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque, in.
Modi excepturi voluptatibus expedita voluptas laborum veritatis error adipisci doloremque. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid cum asperiores dicta, magnam quibusdam veniam nemo aperiam sit quas fugiat?
Modi excepturi voluptatibus expedita voluptas laborum veritatis error adipisci doloremque. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid cum asperiores dicta, magnam quibusdam veniam nemo aperiam sit quas fugiat?
哈!測試結果是可以的哦,只要把原本單一個 p.text 用 div.text 取代,再將正常的複數文字段落 p 塞在被置中過的 div.text 就可以囉。
個人覺得這一版的 CSS 垂直置中(vertical centering)技巧不僅寫的 Code 很少,應用方式又多,在實戰應用上可以說是超級方便呀!在這裡要向發明這個 CSS 技巧的神人致敬!
簡易方法A - 利用 CSS3 的 transform: translate
本方法適用於外層高度已知(或固定),但內容為未知高度的 Block 元素垂直置中
HTML
1
2
3
4
5
|
< div class = "wrapper3" > < div class = "child block" > I am a unknown height block level box </ div > </ div > |
CSS
1
2
3
4
5
6
7
8
|
.wrapper 3 { position : relative ; } .wrapper 3 .child { position : absolute ; top : 50% ; transform: translateY( -50% ); } |
Demo
CSS看起來有沒有覺得似曾相識?呵,本方式和之前其中一個方法,利用 top: 50% 再設 margin-top: (本体高度一半的負值) 原理一樣,只是用 css3 的 transform: translateY 更聰明,可以直接設為負50%,也就是不必知道本身的高度也可以達成垂直置中的目的。
缺點
因為被置中的元素必須為絕對定位,所以在實務應用上可能會有點難用。
簡易方法B - Block 級元素設置上下一樣的 padding
這方法其實算有點偷懶啦,但其實有的時候,你想要的效果不就只是這樣而已嗎?XD
沒有一定最好用的CSS,只有最適合用的CSS
HTML
1
2
3
4
5
|
< div class = "menu-demo" > < div class = "child" >Home</ div > < div class = "child" >Store</ div > < div class = "child" >About</ div > </ div > |
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
.menu-demo { text-align : center ; background-color : indianred; padding : 6px 0 ; } .menu-demo .child { min-width : 120px ; display : inline- block ; text-align : center ; color : #E00 ; background-color : pink; /* Point */ padding-top : 30px ; padding-bottom : 30px ; } |
demo
demo2
優點
根本就超級偷吃步,秒懂 XD。
另外,比起 height = line-height 作法來說,它是可以斷行的(如果只有它自己一個的話啦),兩個以上群組還是建議高度一致,如上面展示。
缺點
只適合小東西用,Menu or Button 等等,或是有時候你的元素因某些原因無法設置 padding 時就沒辦法用。
方法C: 很多不同比例圖片同時陳列時的垂直置中法 - CSS3 Object fit
Example
購物網站常有的 Layout 比例不一的產品照片列表
如果是你,你會怎麼刻 HTML Layout 呢?大概會像這個樣子吧
HTML
1
2
3
4
|
< div class = "prod" > < div class = "prod-caption" >This is a good product</ div > </ div > |
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
.prod { float : left ; width : 200px ; min-height : 200px ; border : 1px solid #747474 ; margin-right : 10px ; padding : 10px ; box-sizing: border-box; } .prod-thumbnail { display : block ; margin : 0 auto ; } .prod- caption { line-height : 1.2 ; font-size : 12px ; margin : 6px auto ; } |
Demo - Before
最常遇到的例子就是:當你接到電子商務網站的案子,需要做「圖文式產品列表頁」的時候,絕大多數的案例,業者並不會提供你「固定比例」的圖片,一定是有正方、有長、有扁,比例都不同,水平置中當然沒問題,垂直呢?哈哈哈,搞死你……
上面的 mockup 刻出來之後,就會像樂天網站的 Layout 一樣,直方型和正方形品圖都是水平+垂直置中的沒問題,但是扁長型的圖片就只能靠上齊了。
當然,這個時候,你可以用上面新增 :before
偽類的方法在 .prod
加一些 css 來調整,但注意到這裡的矩型裡面除了圖片之外,還有文字,所以你要考慮的地方不是很單純。
有另一個更簡單的方式,就是用 CSS3 針對 image 提供的新屬性 object-fit
設定為 contain
就可以完美達成任務。
CSS
1
2
3
4
5
6
7
8
9
|
.prod-thumbnail { display : block ; margin : 0 auto ; /* Point */ width : 130px ; height : 130px ; object-fit: contain; /* 在130正方的空間完整地將圖片顯示出來 */ } |
Demo - After (PS:淺藍底色是為 demo 加上的,object-fit 本身不會在 image 背景加色)
object-fit 是目前最新的 css3 image 屬性,它的用途很直覺且很強大。object-fit 更好玩的除了 contain 還有 cover,目前坊間看到許多「整頁背景」部分就是利用另一個相似用途的 background-size: cover
來做的。如果你對它有興趣可以去 Google 一下 :D 或是改天再來寫篇專文介紹。
優點
一行 css 就解決了圖片垂直置中,你以前還要寫一堆 css hack 或 javascript !!!
缺點
支援度尚無法稱為完整,在本文撰寫時間點(2015.02.13)時,firefox 最新版(35.0)尚無支援,但好消息是下一版本(36.0)的 firefox 即將支援 css3 的 object-fit。
IE? 就別理它了吧……XDDD 詳細的 Support list 請至這裡查看
方法D - 你有聽過安麗嗎?噢不!是 flexbox
同方法C一樣,是 CSS3 很強大的屬性,如果你有聽過 flexbox 且知道怎麼做,css vertical centering 根本是 piece of cake!
CSS
1
2
3
4
5
|
.parent { display : flex; flex- direction : column; justify- content : center ; } |
Demo
結論:純 CSS Vertical Centering Div 垂直置中是可以做到,而且方法非常多元的。