聖杯和雙飛翼布局介紹
最近正好碰到了寫這種布局,一直沒有總結過正好借這次機會總結一波,同時加強一下自己的理解。
博客鏈接:www.xluos.com/index.ph...
聖杯布局和雙飛翼布局作為經典的三欄式布局是面試中的常客。兩種布局達到效果上基本相同,都是兩邊兩欄寬度固定,中間欄寬度自適應。在HTML結構上中間欄在最前面保證了最先渲染中間提升性能(因為這兩種布局都比較老,我認為在現代瀏覽器中這點兒性能優化效果並不是很大),並且兼容性良好。兩種布局的實現方法前半部分相同,后半部分的實現各有利弊,下面會簡單介紹兩者的區別。
Demo和代碼
兩種布局的實現
首先,既然是三欄式布局我們需要三個div
<header>聖杯布局</header>
<div class="bd">
<div class="main text">
main
</div>
<div class="left text">
left
</div>
<div class="right text">
right
</div>
</div>
<footer>footer</footer>
給main
設置width: 100%
,讓它始終占滿窗口,這樣才有自適應的效果。
然后我們給它加上點兒樣式區分,效果如下:
為了形成在一行三欄布局,給三個方塊都加上浮動float: left;
(注意清除浮動,因為浮動會導致父元素高度塌陷)
接着我們要把三個方塊拉到一行,這里要利用負margin的技巧。
- left要放到main的左邊,設置
margin-left: -100%
,因為margin
的百分比是相對與父元素的,所以需要整整一行的寬度才能補償這個margin的值,所以left就能到main的左邊。 - 接着讓right到main的右邊,只需要設置
margin-left
的值為負的right的寬,比如margin-left: -200px;
,正好使main重疊right的寬度,因為設置了浮動所以right就會到main的右邊了。
下面我們來看一下效果:
看樣子好像我們已經成功達到了效果?不要急給兩個方塊變透明,再給中間加點兒內容看看。
我們發現當內容變多之后,因為三個方塊都是設置的浮動,脫離的文檔流,兩邊固定寬度的兩欄會擋住我們的內容。
所以要想兩邊不遮擋內容,就需要中間欄給兩邊的位置騰出來。我們可以想到padding
和margin
都可以用來騰出位置,這兩個屬性就是聖杯布局的雙飛翼布局的區別,不過雙飛翼布局還需要稍微改造一下HTML的結構,這個等一下再說。
1.聖杯布局——使用padding
屬性
- 第一步:為三個元素的父元素加上
padding
屬性,騰開位置 - 第二步:由於騰開位置后會產生空白,所以使用
position: relative;
屬性來移動左右兩欄,這樣就不會遮擋了。
不過這樣布局有一個問題就是:有一個最小寬度,當頁面小於最小寬度時布局就會亂掉。所以最好給body
設置一個min-width
。這個min-width
肯定不能是試出來的,怎么計算呢?就是left-width * 2 + right-width,至於為什么,簡單的說就是:“由於設置了相對定位,所以當left原來的位置和right的位置產生重疊時,由於浮動的原因一行放不下就會換行”。所以布局就被打亂了。使用雙飛翼布局就可以避免這個問題。
2.雙飛翼布局——使用margin
屬性
首先我們要對HTML結構稍微改變一下:
<header>雙飛翼布局</header>
<div class="bd">
<div class="main text">
<div class="main-content">main</div>
</div>
<div class="left text">
left
</div>
<div class="right text">
right
</div>
</div>
<footer>footer</footer>
可以看到,我們在main
里面又加了一個內容層。如果知道盒子模型,就知道我們是不能直接給main
添加margin
屬性,因為我們已經設置了width:100%
,再設置margin
的話就會超過窗口的寬度,所以我們再創造一個內容層,將所有要顯示的內容放到main-content
中,給main-content
設置margin
就可以了。
- 因為不改變父元素所以只需要給
main-content
設置margin: 0 200px 0 200px;
屬性就可以了達到效果
兩種布局的區別
聖杯布局是中間欄為兩邊騰開位置。
雙飛翼布局則是中間欄不變,將內容部分為兩邊騰開位置