前端布局模型
一、CSS包含3種基本的布局模型,用英文概括為:Flow、Layer 和 Float。
在網頁中,元素有三種布局模型:
1、流動模型(Flow)
-
流動模型是默認的網頁布局模式。
-
在流動模型下,內聯元素都會在所處的包含元素內從左到右按順序水平分布顯示。
- 在流動模型下,塊狀元素都會在所處的包含元素內自上而下按順序垂直延伸分布,在默認狀態下,塊狀元素的寬度都為100%。
2、浮動模型 (Float)float:right/left/none;
- 任何元素在默認情況下是不能浮動的,但可以用 CSS 定義為浮動
3、層模型(layer)絕對定位position: absolute; 相對定位position: relative; 固定定位position: fixed;
- 對每個圖層能夠精確定位操作
解釋
- absolute:如果想為元素設置層模型中的絕對定位,需要設置position:absolute(表示絕對定位),這條語句的作用將元素從文檔流中拖出來,然後使用left、right、top、bottom屬性相對於其最接近的一個具有定位屬性的父包含塊進行絕對定位。如果不存在這樣的包含塊,則相對於body元素,即相對於瀏覽器窗口。
- relative:如果想為元素設置層模型中的相對定位,需要設置position:relative(表示相對定位),它通過left、right、top、bottom屬性確定元素在正常文檔流中的偏移位置。相對定位完成的過程是首先按static(float)方式生成一個元素(並且元素像層一樣浮動了起來),然後相對於以前的位置移動
- fixed:表示固定定位,與absolute定位類型類似,但它的相對移動的坐標是視圖(屏幕內的網頁窗口)本身。由於視圖本身是固定的,它不會隨瀏覽器窗口的滾動條滾動而變化,除非你在屏幕中移動瀏覽器窗口的屏幕位置,或改變瀏覽器窗口的顯示大小,因此固定定位的元素會始終位於瀏覽器窗口內視圖的某個位置,不會受文檔流動影響,這與background-attachment:fixed?屬性功能相同。
CSS布局經典—聖杯布局與雙飛翼布局
聖杯布局與雙飛翼布局針對的都是三列左右欄固定中間欄邊框自適應的網頁布局(想象一下聖杯是主體是加上兩個耳朵;鳥兒是身體加上一對翅膀),聖杯布局是Kevin Cornell在2006年提出的一個布局模型概念,在國內最早是由淘寶UED的工程師(傳說是玉伯)改進並傳播開來,在中國也有叫法是雙飛翼布局,它的布局要求有幾點:
-
三列布局,中間寬度自適應,兩邊定寬;
-
中間欄要在瀏覽器中優先展示渲染;
-
允許任意列的高度最高;
下面我們看看具體的實現方法。
一、聖杯布局
HTML結構
1 2 3 4 5 6 7 |
< div class = "header" >header</ div >
< div class = "container" >
< div class = "main" >main</ div >
< div class = "left" >left</ div >
< div class = "right" >right</ div >
</ div >
< div class = "footer" >footer</ div >
|
因為需要中間欄優先展示渲染,所以中間的main在HTML的結構中卻是最靠前的。在實際的網站中這樣做的好處就是用戶能夠先看到網頁正文信息,一般網頁兩邊的導航信息和說明信息我們認為優先級沒有正文重要。
1.設置一下基本樣式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
*{ margin : 0 ; padding : 0 ;}
body{ min-width : 700px ;}
.header,.footer{
border : 1px solid #333 ;
background : #aaa ;
text-align : center ;
}
. left ,.main,. right {
min-height : 130px ;
}
.container{
border : 2px solid yellow;
}
. left {
width : 200px ;
background : red ;
}
. right {
width : 220px ;
background : green ;
}
.main{
background : blue ;
}
|
為了高度保持一致給left middle right都加上min-height:130px
2.將主體部分的三個子元素都設置左浮動
1 2 3 |
. left ,.main,. right {
float : left ;
}
|
此時的頁面顯示如圖所示,Shen Me Gui沒關系,事情會變得好起來的
我們看一下上面的效果比較明顯的兩個問題,一是footer跑到上面去了,二是container容器高度塌陷了,這是典型的“清除浮動和閉合浮動”問題。
3.解決浮動問題
1 2 3 4 5 6 7 |
.container{
border : 2px solid yellow;
overflow : hidden ; /*閉合浮動*/
}
.footer{
clear : both ; /*清楚浮動*/
}
[附]清浮動常用的方法
.clearfix:after{
content:"";
display:block;
clear:both
}
.clearfix{
*zoom:1; /*解決兼容性問題*/
}
|
給container加上overflow:hidden觸發BFC閉合浮動,給footer加上clear屬性清除浮動。
我們發現footer移到了下面,並且container的高度塌陷也修復了。
4.設置main寬度為width:100%,讓其單獨占滿一行
1 2 3 4 |
.main{
width : 100% ;
background : blue ;
}
|
5.設置left和right負的外邊距
我們的目標是讓left、main、right依次並排,但是上圖中left和right都是位於下一行,這裏的技巧就是使用負的margin-left:
1 2 3 4 5 6 7 8 9 10 |
. left {
margin-left : -100% ;
width : 200px ;
background : red ;
}
. right {
margin-left : -220px ;
width : 220px ;
background : green ;
}
|
負的margin-left會讓元素沿文檔流向左移動,如果負的數值比較大就會一直移動到上一行。關於負的margin的應用也是博大精深,這裏肯定是不能詳細介紹了。
設置left部分的margin-left為-100%,就會使left向左移動一整個行的寬度,由於left左邊是父元素的邊框,所以left繼續跳到上一行左移,一直移動到上一行的開頭,並覆蓋了main部分(仔細觀察下圖,你會發現main裏面的字“main”不見了,因為被left遮住了),left上移過後,right就會處於上一行的開頭位置,這是再設置right部分margin-left為負的寬度,right就會左移到上一行的末尾。
6.修復覆蓋問題
第五步我們說過設置left和right負的外邊距覆蓋了main部分的內容,現在想辦法修復這個問題,首先給container的左右加上一個內邊距,分別為left和right的寬度。
1 2 3 4 5 |
.container{
border : 2px solid yellow;
padding : 0 220px 0 200px ;
overflow : hidden ;
}
|
由於left、main、right三個部分都被container包裹著,所以給其添加內邊距,三個子元素會往中間擠。貌似還是沒有修復問題,別著急,我們已經在container的左右兩邊留下了相應寬度的留白,只要把left和right分別移動到這兩個留白就可以了。可以使用相對定位移動left和right部分,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
. left ,.main,. right {
position : relative ;
float : left ;
min-height : 130px ;
}
. left {
margin-left : -100% ;
left : -200px ;
width : 200px ;
background : red ;
}
. right {
margin-left : -220px ;
right : -220px ;
width : 220px ;
background : green ;
}
|
至此,我們完成了三列中間自適應的布局,也就是傳說中的聖杯布局。完整的代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< title >聖杯布局</ title >
< style type = "text/css" >
*{margin: 0;padding: 0;}
body{min-width: 700px;}
.header,
.footer{
border: 1px solid #333;
background: #aaa;
text-align: center;
}
.left,
.main,
.right{
position: relative;
float: left;
min-height: 130px;
}
.container{
border: 2px solid yellow;
padding:0 220px 0 200px;
overflow: hidden;
}
.left{
margin-left: -100%;
left: -200px;
width: 200px;
background: red;
}
.right{
margin-left: -220px;
right: -220px;
width: 220px;
background: green;
}
.main{
width: 100%;
background: blue;
}
.footer{
clear: both;
}
</ style >
</ head >
< body >
< div class = "header" >header</ div >
< div class = "container" >
< div class = "main" >main</ div >
< div class = "left" >left</ div >
< div class = "right" >right</ div >
</ div >
< div class = "footer" >footer</ div >
</ body >
</ html >
|
二、雙飛翼布局
聖杯布局和雙飛翼布局解決問題的方案在前一半是相同的,也就是三欄全部float浮動,但左右兩欄加上負margin讓其跟中間欄div並排,以形成三欄布局。不同在於解決”中間欄div內容不被遮擋“問題的思路不一樣。
HTML 結構
1 2 3 4 5 6 7 8 9 |
< div class = "header" >header</ div >
< div class = "container" >
< div class = "main" >
< div class = "content" >main</ div >
</ div >
< div class = "left" >left</ div >
< div class = "right" >right</ div >
</ div >
< div class = "footer" >footer</ div >
|
雙飛翼布局的前五步和聖杯布局完全相同,我們只需要修改第六步,前面是設置container的內邊距以及相對定位來解決這個覆蓋問題的,雙飛翼布局中,為了main內容不被遮擋,在main裏面添加一個子元素content來顯示內容,然後設置content的margin-left和margin-right為左右兩欄div留出位置。
直接貼出代碼,讀者可以自行參透他們的異同:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< title >聖杯布局</ title >
< style type = "text/css" >
*{margin: 0;padding: 0;}
body{min-width: 700px;}
.header,
.footer{
border: 1px solid #333;
background: #aaa;
text-align: center;
}
.left,
.main,
.right{
float: left;
min-height: 130px;
}
.container{
border: 2px solid yellow;
overflow: hidden;
}
.left{
margin-left: -100%;
width: 200px;
background: red;
}
.right{
margin-left: -220px;
width: 220px;
background: green;
}
.main{
width: 100%;
background: blue;
}
.content{
margin: 0 220px 0 200px;
}
.footer{
clear: both;
}
</ style >
</ head >
< body >
< div class = "header" >header</ div >
< div class = "container" >
< div class = "main" >
< div class = "content" >main</ div >
</ div >
< div class = "left" >left</ div >
< div class = "right" >right</ div >
</ div >
< div class = "footer" >footer</ div >
</ body >
</ html >
|
雙飛翼布局比聖杯布局多使用了1個div,少用大致4個css屬性(聖杯布局container的 padding-left和padding-right這2個屬性,加上左右兩個div用相對布局position: relative及對應的right和left共4個屬性,;而雙飛翼布局子div裏用margin-left和margin-right共2個屬性,比聖杯布局思路更直接和簡潔一點。簡單說起來就是”雙飛翼布局比聖杯布局多創建了一個div,但不用相對布局了。
前端布局模型