頁面佈局經常使用的方式有兩種,浮動(float)和定位(position),定位已經講過了(關於position定位及z-index的理解),這篇主要講浮動,而浮動和清理浮動是成對出現的,因此也一併講了。css
理解浮動前,咱們須要一些前置條件:1. 盒模型; 2. 文檔流;html
1. 盒模型css3
一個元素的width或者height屬性和它的實際寬度或高度是一致的嗎?固然不是,咱們看下盒模型就知道了。瀏覽器
css盒模型具有4大屬性: content(內容),padding(填充),border(邊框),margin(邊界)。佈局
我 們能夠這樣來理解,把它想象成一臺彩電。裏面的彩電就是content(內容),防震的泡沫塑料就是padding(填充),外面的紙盒子就是 border(邊框),彩電存放在庫房的時候不能擠壓,每一個之間要有必定的空隙通風,這個空隙就是margin(邊界),width和height就至關 於彩電的寬和高(只是拿來舉例子增強理解,不要太較真哦,呵呵)。3d
那麼咱們計算一個庫房能放多少彩電怎麼算?只計算彩電的寬(width)和高(height)嗎?確定不是,一臺彩電的佔地面積除了彩電自身的寬(width)和高(height)外,還要加上泡沫塑料的厚度(padding),紙盒子的厚度(border),彩電與彩電之間的空隙(margin)。以下圖:htm
因此一個元素的實際佔據空間大小應該這樣計算:blog
boxWidth = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right;圖片
boxHeight= margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom ;文檔
OK,盒模型到此結束。
2. 文檔流(可參考 關於position定位及z-index的理解中的前半部分)
浮動元素也會脫離文檔流。
開始浮動的講解:
先來個例子:
css:
#box {
width: 500px;
border: 1px solid #d9d9d9;
}
#left {
width: 200px;
height: 150px;
background: #54c9e8;
}
#right {
width: 300px;
height: 150px;
background: #e678cc;
}
html:
<div id="box">
<div id="left"></div>
<div id="right"></div>
</div>
效果如圖:
咱們並無給任何一個元素添加float屬性,默認顯示塊級元素獨佔一行(關於塊級元素,行內塊,行內元素此篇不作詳細解釋,會在以後另外介紹)。#box(灰線區)沒有設置height屬性,可是默認會隨着內容的高度變化而變化。
當咱們給#left(藍色區)設置 float: left;時,效果以下圖:
咱們發現#left(藍色區)向左浮動後,擋在了#right(紅色區)上面,前面咱們也瞭解了,浮動的元素是脫離文檔流的,因此#right(紅色區)佔據了#left(藍色區)原先的位置,與#left(藍色區)重疊。
若是咱們讓#right(紅色區)也向左浮動,那麼會產生下面這種現象,如圖:
#left(藍色區)和#right(紅色區)在一行了,這就是咱們想要的效果,將兩個塊級元素放在同一行,可是等等,彷佛還有點問題,框呢?咱們的#box(灰線區)怎麼成一根線了?回味一下咱們剛纔所理解的:浮動元素脫離文檔流。明白了麼?雖然#left(藍色區)和#right(紅色區)都是#box(灰線框)的子元素,可是兩個都用了 float: left; 進行左浮動,脫離了文檔流,原來的#box(灰線區)至關於空了,塊級元素默認寬度100%,高度0,因此產生#box(灰線區)沒有高度,border-top和border-bottom貼在一塊兒的現象。不只父元素會受影響,後面的其餘元素也可能會受影響。
在解決這個問題前,咱們須要瞭解關於浮動的定義:
浮動的框能夠向左或向右移動,直到它的外邊緣碰到包含框或另外一個浮動框的邊框爲止。因爲浮動框不在文檔的普通流中,因此文檔的普通流中的塊框表現得就像浮動框不存在同樣。
好了,能夠着手解決問題了。解決的方式有兩種,一種是讓它們都浮起來,這樣你們都脫離文檔流,都在一個層上了,天然就沒問題了。另外一種是清理掉浮動(clear)。
第一種:#box(灰線區)浮起來
給#box增長float: left;屬性
第二種:清理浮動
咱們增長一個.clear的class,在#right(紅色區)後面增長一個空div而且使用clear。更改後代碼以下:
css:
#box {
width: 500px;
border: 1px solid #d9d9d9;
}
#left {
float: left;
width: 200px;
height: 150px;
background: #54c9e8;
}
#right {
float: left;
width: 250px;
height: 150px;
background: #e678cc;
}
.clear {
clear: both;
}
html:
<div id="box">
<div id="left"></div>
<div id="right"></div>
<div class="clear"></div>
</div>
兩種方式都會獲得以下圖效果:
對 於第一種都浮起來,可能比較好理解,畢竟你們都同樣了,誰也不能搞特殊了,因此效果正常了,#left(藍色區)和#right(紅色區)沒辦法 從#box中跑出來了。第二種清理浮動可能不大好理解。咱們須要研究下clear這個屬性。因此咱們須要瞭解下清除浮動的定義:
clear 屬性定義了元素的哪邊上不容許出現浮動元素。在 CSS1 和 CSS2 中,這是經過自動爲清除元素(即設置了 clear 屬性的元素)增長上外邊距實現的。在 CSS2.1 中,會在元素上外邊距之上增長清除空間,而外邊距自己並不改變。
根 據以上定義咱們能夠這樣理解:#left(藍色區)和#right(紅色區)進行浮動後,脫離了#box(灰線區)的控制,#box(灰線區)至關於裏面 沒有內容,根據默認塊級元素表現,#box(灰線區)是一個寬度100%,高度爲0的div,而使用clear的div沒有浮動,而且使用了clear屬 性,那麼根據清除浮動的定義,這個div會在它的上方空出來足夠容納#left和#right的空白,因此#box(灰線區)就被撐開了,雖 然#left(藍色區)和#right(紅色區)仍是不受它的控制,可是看起來是被它控制着,而使用clear的空div自己沒有設置寬度和高度,根據默 認塊級元素表現,它也是個寬度100%,高度爲0的元素,也便是說,它是不顯示的。
接下來講一些要注意的地方和技巧
1. 右邊浮動與左浮動順序相反
左浮動:
css:
#box {
width: 500px;
border: 1px solid #d9d9d9;
}
#left {
float: left;
width: 200px;
height: 150px;
background: #54c9e8;
}
#right {
float: left;
width: 250px;
height: 150px;
background: #e678cc;
}
.clear {
clear: both;
}
html:
<div id="box">
<div id="left"></div>
<div id="right"></div>
<div class="clear"></div>
</div>
效果如圖:
右浮動:
css:
#box {
width: 500px;
border: 1px solid #d9d9d9;
}
#left {
float: right;
width: 200px;
height: 150px;
background: #54c9e8;
}
#right {
float: right;
width: 250px;
height: 150px;
background: #e678cc;
}
.clear {
clear: both;
}
html:
<div id="box">
<div id="left"></div>
<div id="right"></div>
<div class="clear"></div>
</div>
效果如圖:
發現有什麼不一樣了麼?html順序同樣甚至css順序也同樣,可是兩個色塊位置徹底相反。咱們回顧一下浮動的定義就明白了:直到它的外邊緣碰到包含框或另外一個浮動框的邊框爲止。 按照html中得順序,#left(藍色區)在前面,#right(紅色區)在後面,因此,都向左浮動時,#left(藍色區)先向左浮 動,#right(紅色區)再向左浮動,當碰到#left(藍色區)時中止,都向右浮動時,仍是#left(藍色區)先向右浮動,而後#right(紅色 區)再向右浮動,一樣碰到#left(藍色區)中止,因此就產生了以上兩種效果。
2. 浮動元素的寬度
2.1 浮動元素相加實際寬度大於父元素寬度致使換行
css:
#box {
width: 600px;
overflow: hidden;
border: 1px solid #d9d9d9;
}
.box_i {
width: 200px;
height: 100px;
float: left;
margin: 10px;
background: #54c9e8;
}
html:
<div id="box">
<div class="box_i"></div>
<div class="box_i"></div>
<div class="box_i"></div>
</div>
效果如圖:
也 許有人會問#box(灰線區)寬600px,每一個.box_i(藍色區)寬都是200px,按說恰好,應該在一行,怎麼第三個下來了呢?有這疑問的同窗往 上看盒模型部分,元素實際佔據的寬高是要加上margin值的,因此上面.box_i(藍色區)的width應該是180px(200-10*2)。
2.2 浮動元素被卡住
css:
#box {
width: 600px;
overflow: hidden;
border: 1px solid #d9d9d9;
}
#box1 {
width: 300px;
height: 150px;
float: left;
background: #e678cc;
}
#box2 {
width: 300px;
height: 100px;
float: left;
background: #54c9e8;
}
#box3 {
width: 300px;
height: 100px;
float: left;
background: #8add66;
}
html:
<div id="box">
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
</div>
效果如圖:
是否是感受很奇怪?按照浮動原理,#box1(紅色區)和#box2(藍色區)把#box(灰線區)佔滿了,剩餘的空間不足以放下#box3(綠色區),因此#box3(綠色區)應該浮動到最左邊,在#box1(紅色區)下面,可是怎麼會在這個位置卡住呢?
事實是#box3(綠色區)確實被#box1(紅色區)卡住了,咱們再次複習下浮動的定義:浮動的框能夠向左或向右移動,直到它的外邊緣碰到包含框或另外一個浮動框的邊框爲止。
好 了,根據定義從新分析一遍。#box1(紅色區)和#box2(藍色區)浮動把#box(灰線區)佔滿了,剩餘的空間不足以放下#box3(綠色 區),#box3(綠色區)也浮動,只能換行,因爲#box1(紅色區)比#box2(藍色區)高出一部分,#box3(綠色區)在換行浮動的時候 和#box2(藍色區)同樣碰到了#box1(紅色區),既然碰到了另外一個浮動框的邊框,那就停在這吧,因此就成上圖這樣了。
那麼,若是咱們想讓#box3(綠色區)放在#box1(紅色區)底下怎麼辦?固然是清除浮動了:
css:
#box3 {
width: 300px;
height: 100px;
clear: both;
background: #8add66;
}
而後就獲得咱們想要的結果了,效果以下圖:
有心的同窗可能已經發現,以前兩個例子好像沒看到clear,可是#box(灰線區)卻不受浮動影響,爲何呢?哈哈,祕密在於 overflow: hidden;文章末尾會專門講解浮動的清理。
3. 關於圖文混排
通用html:
<div id="box">
<img src="aa.jpg" alt="">
<p>11 月4日,受強冷空氣影響,我國北方大部分地區出現大範圍降溫雨雪天氣,其中華北、東北、內蒙古及山東半島等地出現中到大雪。11月3日晚至4日夜,京城遭 受這次寒潮過程最嚴重的影響,雨雪、雷電、降溫和大風同時影響北京各地。市氣象臺根據降雨量和降雪量的整體統計,昨日全市降水量至中午便超過歷史極值。而 延慶降雪量則爲52年來最大暴雪。</p>
</div>
3.1 默認
示例:
css:
#box {
font: 12px/18px Arial;
color: #4d4d4d;
width: 500px;
}
效果如圖:
3.2 圖片文字同時浮動
css:
#box {
font: 12px/18px Arial;
color: #4d4d4d;
width: 500px;
}
#box img {
float: left;
padding-right: 10px;
}
#box p {
float: left;
width: 350px;
margin: 0;
}
效果如圖:
3.3 圖片浮動,文字不浮動,實現文字環繞圖片
css:
#box {
font: 12px/18px Arial;
color: #4d4d4d;
width: 500px;
}
#box img {
float: left;
padding-right: 10px;
}
效果如圖:
關於清除浮動
前面咱們已經講了什麼是清除浮動,以及爲何要清除浮動。如今講下浮動的清理方法。
清理浮動的經常使用方法的有3種外加1種ie專屬。
1. 父元素overflow: hidden;
我 們前面用過了,這種清除浮動的使用方法是:子元素進行了浮動,給父元素添加overflow: hidden;便可清除子元素浮動對父元素的影響。好比一 個ul列表,當li進行浮動後,ul沒有浮動,天然受到li浮動的影響,沒有高度,這時給ul增長添加overflow: hidden;便可清除li浮 動對ul的影響。
原理:overflow屬性會產生包裹效果,這就勢必須要得到子元素的寬和高,因此變相達到了清理浮動的效果。
限制:使用這種清理方式的父元素不能或者儘可能不要設置高度,好比li浮動,ul添加overflow: hidden;不要設置高度height屬性。
支持:全部瀏覽器
2. 空元素clear
這種咱們前面也用過。須要咱們創建一個class: .clear { clear: both; }。
使用方法:在須要清理的浮動元素後面增長一個空標籤,好比div,並使用.clear。
弊端: 對於須要大量清理浮動的頁面,會產生大量額外標籤。
支持:全部瀏覽器
3. :after僞類清理
:afer屬性是css3中新加的屬性,意思是在元素內容末尾添加內容。:after中的content屬性能夠設置追加內容。這用清除方式原理同空元素clear,區別是不用使用無心義的空標籤了。
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
}
使用方法:同overflow清除浮動方法,子元素浮動對父元素形成影響,能夠給父元素使用.clearfix。
原 理: 在元素內容末尾追加空內容,並設置爲塊級屬性,高度爲0,即不可見,而後清除掉以前元素的浮動。例如,ul列表中的li進行浮動,ul使用了 clearfix後,:after標籤就像a:hover同樣,會有一個行爲,這個行爲就是在ul的內容最末尾,也就是最後一個li的後面增長一個空內容 (content: ""),並將其設置爲塊,高度設爲0不可見,並設置clear: both; 將浮動的li清理掉。
支持:全部支持:after屬性的瀏覽器
4. ie專屬zoom
zoom: 1;
zoom 是ie系列專屬屬性,用來進行放大,zoom: 1;的意思的放大1倍,也就是原大小。在ie系列中,使用zoom的元素會自動得到layout,達到清 除浮動的效果,固然主要是針對之前的版本IE6和IE7有效,由於IE8以後改動較大,zoom再也不能觸發layout屬性因此沒法達到清除浮動的效果, 可是我在網上查閱了一些資料,發現IE8分爲IE8(Q)和IE8(S)(我不知道這是什麼意思,知道的請告訴我,呵呵),IE8(Q)不支 持:after屬性,可是zoom能夠觸發layout,IE8(S)支持:after可是zoom不能觸發layout。能夠參考一下兩篇文章:
RM3007: 在 IE6 IE7 IE8(Q) 中包含被清除浮動的浮動元素的塊級元素的背景在某些狀況下不是設置值
RS8010: IE6 IE7 IE8(Q) 不支持 ':before' 和 ':after' 僞元素
根據以上特性,咱們能夠寫出一個通用型的清理浮動:萬能清理浮動寫法