自適應的多列圖文混排改進
關於網頁兩欄、三欄的佈局討論由來已久,有各種各樣上佳的方案。本文重點討論的不是兩欄、三欄佈局這樣通用的解決方案,而是一個專門針對兩欄圖文混排的特定需求的改進型方案。當然其中的原理也可以被應用於兩欄佈局甚至更多,那是你舉一反三,不是本文討論的重點。你也可以先看一下最終的示例頁面。
開始之前,首先來看一下我們的需求:
- 一個通用的結構,可以放在不同寬度的佈局列中;
- 該結構基本構成為左圖(頭像)右文(多種結構),左右寬度均不固定;
- 左欄寬度由內容最小寬度確定,右欄無論內容多少要佔滿容器剩餘寬度;
- 右欄可能有定位元素超出自身範圍,要予以顯示,且右欄的內容不能環繞左欄;
- 右欄中可能會再包含浮動,因此右欄需要清除自身內容的浮動。 實際上針對類似需求,網上也有不少方案,建議參考閱讀
這篇長文以及濤哥簡練實用的自適應的圖文混排。根據需求,我們能確定出最基本的結構:
<div class="img-txt">
<div class="img">左圖</div>
<div class="txt">右文</div>
</div>
安裝兩列布局的傳統做法,我們可以想到兩列都浮動、左欄浮動+右欄左邊距以及負邊距等很多方案。但是再對比一下需求,右欄的特性否決了兩欄都浮動的方式,左欄的寬度不固定否定了負邊距的方式。左欄浮動加右欄左邊距將會遭遇[cref bfc-element-margin-bug-in-webkit webkit核心瀏覽器的BFC元素邊距bug]。 所以我們只能選擇左欄浮動(浮動元素寬度最小,內容可以撐開),右欄不浮動(不浮動的block元素預設佔滿行寬)。但是不浮動的右欄既不能環繞左欄,又不能加左邊距。怎麼辦?理所當然的就該想到BFC元素了。
濤哥的方案就是這樣出來的。我們在騰訊朋友的專案中已經非常大量地實踐了這種方案,效果不錯。該方案的核心是右欄通過overflow:hidden來建立一個塊級上下文(Block Formatting Context),這樣同時滿足了右欄寬高自適應和不環繞左欄兩個需求,我的方案也是在此之上的一個改進。 既然已經有了經過實踐驗證的方案,為什麼要改進呢?因為我們在實踐中也遇到了一些麻煩,那就是右欄中的複雜內容,複雜到會有溢位容器的浮層。但是overflow:hidden的存在迫使我們必須把右欄裡的定位元素放到右欄結構之外。雖然能解決問題,但是結構上就不符合邏輯了。 所以我們的需求可以抽象為兩點:一、建立塊級上下文;二、不能使用overflow:hidden。前幾天我翻譯了一篇文章在[cref the-hacktastic-zoom-fix-translation 非IE瀏覽器中模擬zoom建立塊級上下文],恰好解決了這個矛盾——在IE中用zoom建立塊級上下文,在其它瀏覽器中模擬IE的zoom建立塊級上下文。 回到我們的結構中來說: * img-txt要清除浮動(否則當右欄高度小於左欄時,img-txt的高度撐不開),關於清除浮動的方式,之前已經給出了[cref clearfix-reloaded-overflowhidden-demystified-translation 改進的方案]。 * img要左浮動,img和txt之間的距離只能加在img上(原因之前說了,webkit的bug)。 * txt要建立BFC,要清除浮動(這兩個問題在模擬zoom的時候一併解決了)。 有了這些前提,我的方案得來全不費功夫。首先是img-txt容器清除浮動:
.img-txt:before,
.img-txt:after {
content: ".";
display: block;
height: 0;
visibility: hidden;
}
.img-txt:after {clear: both;}
.img-txt {zoom: 1;}
然後是img的左浮動加右邊距(注意IE6的3畫素文字慢移bug):
.img {
float:left;
margin-right:10px;
_margin-right:7px;
}
然後,txt建立BFC,同時清除自身子元素的浮動:
.txt {
display:table-cell;
#zoom:1;
}
.txt:after {
clear: both;
display: block;
visibility: hidden;
overflow: hidden;
height: 0 !important;
line-height: 0;
font-size: xx-large;
content: " x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x ";
}
行了。現在這個結構就可以搬到網頁上的任意地方去,右欄內部喜歡放文字也好、圖文並茂也好、有浮動也好、有定位也好,都能勝任了。現在如果你再看一下示例頁面,你應該會更容易理解這些例子了。 感謝濤哥,推薦瞭如此精彩的幾篇文章讓我翻譯。