vertical-align 的 CSS 解決方法

這個 IE6 ,實在是讓人吐血,今天,遇到了圖片水平垂直置中的問題,為了要製作看起來漂亮的相簿效果,不論相片是寬是長,是大是小,只要在一定的尺寸以內,都希望它能夠漂漂亮亮的置中;當然,這個相簿本身並不是以 <table> 呈現,而是用 <ul><li> 的列表方式來呈現,也就是說,我當然不能使用 vlaign="middle" 這種方式來做垂直置中。

其實 IE6 除外的瀏覽器,解決方法倒是很簡單,偏偏不能當作沒有 IE6 這個破爛貨,怎麼樣也得解決 IE6 這個惱人的死 BUG ,翻了一下國外的資料,大部分的都是用計算物件中心點的方式來做,但是相片的尺寸就沒有一定,鬼才會知道物件高度的一半是多少,這種方法,實在是對我一點幫助也沒有。

廢話那麼多,到底是解決了沒有?

當然還是解決了,不然我也不會平白寫這篇文章了,為了防止我的嚴重癡呆症發作,還是寫在這邊免得以後忘光光又要重想,煩哩!

先從 HTML 開始,下面是圖檔的 HTML :

<ul class="album">
<li><div><img src="img/01.jpg"></div></li>
<li><div><img src="img/02.jpg"></div></li>
<li><div><img src="img/03.jpg"></div></li>
<li><div><img src="img/04.jpg"></div></li>
<li><div><img src="img/05.jpg"></div></li>
<li><div><img src="img/06.jpg"></div></li>
<li><div><img src="img/07.jpg"></div></li>
<li></li>
<li></li>
</ul>

下面是 CSS 的部份,也就是除了 IE6 以外都可以正常運作的水平垂直置中效果(足見IE6的痴呆程度):

ul.album{list-style-type:none;padding:0px;clear:both;}
ul.album li{width:150px;height:150px;float:left;border:1px solid #FDDAB3;margin:2px;background-color:#FEF4DE;}
ul.album li div{width:150px;height:150px;
display:table-cell;text-align:center;vertical-align:middle;}

以上程式碼會產生如下的顯示:

IE6 以外的瀏覽器,都常
●IE6以外的瀏覽器,相當正常

 

IE6…..遜啊!!!
●IE6中風的樣子

我想HTML的部份就不用說明了,簡單說明一下CSS在這邊所用的技巧。重點在我們對圖片所加的div上面,display:table-cell 讓這個 div 變成類似td的東西出來,也就是說,使用這一招, vertical-align:middle 的屬性就可以在 IE6 以外的瀏覽器正確做到垂直置中的效果。

至於 IE6 ,為了治療 IE6 的痴呆,我們必須要在 HTML 當中加上無聊的 <span> 來幫助我們達到置中的效果:

<ul class="album">
<li><div><span></span><img src="img/01.jpg"></div></li>
<li><div><span></span><img src="img/02.jpg"></div></li>
<li><div><span></span><img src="img/03.jpg"></div></li>
<li><div><span></span><img src="img/04.jpg"></div></li>
<li><div><span></span><img src="img/05.jpg"></div></li>
<li><div><span></span><img src="img/06.jpg"></div></li>
<li><div><span></span><img src="img/07.jpg"></div></li>
<li></li>
<li></li>
</ul>

請注意,我們在<image>前面加上了<span></span>,中間不用放任何內容,因為我們要利用display:inline-block來欺騙使用者的眼睛,針對IE6來更改的CSS如下:

ul.album{list-style-type:none;padding:0px;clear:both;}
ul.album li{width:150px;height:150px;float:left;border:1px solid #FDDAB3;margin:2px;background-color:#FEF4DE;}
ul.album li div{width:150px;height:150px;display:table-cell;text-align:center;vertical-align:middle;}
ul.album li div * {vertical-align:middle;}

*html ul.album li div span{height:100%;display:inline-block;}

我們使用 ul.album li div * {vertical-align:middle;} 來幫助 div 以下的所有元素能夠做到垂直置中,接著的*html,其實是一行只有 IE6 會讀取的CSS hack技巧,我們讓笨笨的 IE6 把這串語法吃下去。請注意,不要傻傻的把這一行放到前面去,CSS這種東西,如果在後面讀到重複的屬性,會把較前面的屬性值給覆蓋掉,這是常識,千萬別忽略掉了!也就是說,在這一行 css hack 語法當中,我們做了display:inline-block 以及 height:100% 的設定,這樣一來,就連在 IE6 上面,也可以正常而且漂亮的置中了。

現在,你可以切換各種瀏覽器來觀看你要的相簿是否都正確顯示了!個人覺得,在影像尺寸是未知數的時候,這是一個解決垂直置中相當漂亮的的方法;雖然CSS排版技巧在跨瀏覽器的時候比起使用表格有比較多需要注意的地方,但是基於網頁效能以及後續維護和保持彈性上,我覺得解決跨瀏覽器的問題所付出的代價還是相當微小的,更重要的是,從這些過程當中,你也可以了解到各個瀏覽器不同的顯示問題,除了幫助你更加了解每個瀏覽器的特性之外,也可以獲得相當多的樂趣唷!(好吧!我自己是樂在其中啦!←變態)

這篇文章的原始參考資料是 Centering (horizontally and vertically) an image in a box ,但是我有針對我自己的需求做了修改,盡量做到簡潔並符合我的最低基本需求,如果需要更完整的資料,有興趣的人可以去原始網站參考一下原作者當初的idea。

Advertisements

18 thoughts on “vertical-align 的 CSS 解決方法

  1. 您好,拜讀過後覺得很棒,所以想要引用您的文章,請問是否可以,另外我也想針對內容的code做修改與原理講解,想徵得您的同意,另外一方面,看到您另外一篇文章說到PCHOME的負面案例之後,對於本篇文章中,在li中包一個div的做法有些覺得不大對,是否應改為包span才對? 這個問題是想與您討論而不是找麻煩喔~您的文章很棒,感謝您的分享,謝謝~

    • To 壞掉的印表機:

      歡迎引用修改喔~

      And…li 當中包含 div 區塊其實並沒有違反 W3C 的 HTML 規範,li 裡面可以包 div、img、p、ol…,但是 div 不能直接包 li,所以,如果有需要在 li 裡面排版,可以使用這種方式來用喔~

      • To Ate:
        我想“壞掉的印表機”想表達的是語意錯誤的部份。
        就好比在文書編輯軟體裡面,列表這個層級是不能去包住段落的,所以它才會說用span才對。也就是ul(or ol)只能包住inline元素(我指的是語意部份,不是css樣式)。

      • To ヒカル:

        在語意上來講,清單這種東西代表的是一種有序或是無序的排列,而這樣的排列,無論是應用於單純的文字、圖像、抑或是圖文並列的內容,在語意上面都是無誤的。

        所謂的清單,正是一種適用於任何性質的排列。

        也因此,li 當中,即便是包含了區塊元件,也是相當符合語意的撰寫方式唷!

    • To 電腦超級賽亞人:

      如果您是指CSS Hack,建議您可以去看看我在CSS分類當中關於CSS Hack的文章,他就是一個針對不同瀏覽器來修正CSS的方法。但是使用的時候要請多多利用CSS繼承的特性,正常來講,如果一般瀏覽器(ex: FF、Opera等)的CSS寫得很正確精簡,你在IE的CSS Hack通常就會只有寥寥幾行,如果寫很多就代表你要回頭去看你原來的CSS囉~

      如果不是CSS Hack的問題,可能就要麻煩您說明您所遇到的狀況或是提供原始碼,不然我應該也猜不太到~:P

  2. 你好~

    在製作網站的時候也遇到類似的問題,剛好有搜尋到你的部落格,在參考了你的內容之後試著仿效在我的案子之中,遇到了一些問題~

    我發現你是利用span的元素製造100%的高度 讓圖片自動跑到中間的位置,但是似乎只是用在內容只有一行的時候 (文字也是單行的狀態)。

    那假如圖片換成多行文字的時候呢? (可能會出現2~3行文字) 利用float去並排元素我想他並不會因此產生類似圖片置中的那種效果,但是空白span跟文字span因為都是行內元素也沒辦法使用 orz。不知道你知不知道如何解決這個問題~

    還是說…只能利用expression去強制運算了 囧!? 我是希望可以盡可能不要用到阿 (哭)

    另外偷偷問一下 不知道關於 IE6跟IE7對於float + margin 會產生 margin 數值 double 的問題,你的解決方案是什麼? 我之前google的方案是利用 display:inline ,但是遇到多行文字就爆炸了,害我寫css一整個瓶頸很大 orz

  3. Pingback: 原來CSS垂直置中可以這樣簡單 | jerry-yang work's logs

  4. Pingback: 垂直對齊 vertical-align 的 CSS 解決方法 | 瑞客設計技術部落格

  5. Pingback: 導覽列 navigator li 垂直法(vertical-align:middle) + li onclick | Alice's Note

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s