寫在開篇:
浮動屬性的設計初衷,只是為了實現文本環繞效果!
時刻牢記這一點,才能正確使用浮動。
由於浮動元素脫離文檔流,它后面的塊級元素會忽略它的存在,占據它原本的位置,但是這個塊級元素中的內聯元素,在流入頁面時會考慮浮動元素的邊界,它們會圍繞着浮動元素。
浮動元素的特征:
1.浮動元素脫離文檔流。
2.浮動元素周圍的外邊距不會合並。
3.浮動元素具有包裹性。
4.浮動元素具有破壞性。
下面這段代碼,能夠驗證上述的四個特征:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>浮動</title> 6 <style> 7 * { 8 margin: 0; 9 } 10 11 .main { 12 width:750px; 13 margin:30px auto; 14 position: relative; 15 } 16 17 .wraper { 18 width:410px; 19 background-color: #ccc; 20 margin-bottom: 30px; 21 } 22 23 .container { 24 background-color: green; 25 width: 350px; 26 margin-left: 30px; 27 } 28 29 .contain { 30 background-color: green; 31 margin-left: 30px; 32 }/*有寬度的容器不會自動收縮,不能體現包裹性,這里去掉容器的寬度*/ 33 34 .float { 35 float:left; 36 } 37 38 .clearfix:after { 39 content: ""; 40 display: table; 41 clear: both; 42 } 43 44 .clearfix { 45 *zoom: 1; 46 } 47 48 .box1 { 49 height: 50px; 50 width: 100px; 51 background-color: red; 52 margin: 20px; 53 } 54 55 .box2 { 56 height: 100px; 57 width: 200px; 58 background-color: blue; 59 margin: 20px; 60 } 61 62 .list { 63 background-color: orange; 64 line-height: 1.5; 65 width: 300px; 66 position: absolute; 67 top: 0; 68 right: 0; 69 } 70 71 li { 72 margin-bottom: 80px; 73 } 74 75 </style> 76 </head> 77 78 <body> 79 <div class="main"> 80 <div class="wraper"> 81 <div class="container"> 82 <div class="box1">box1</div> 83 <div class="box2">box2</div> 84 </div><!--結束container--> 85 </div><!--結束wraper--> 86 <div class="wraper clearfix"> 87 <div class="contain float"> 88 <div class="box1">box1</div> 89 <div class="box2">box2</div> 90 </div><!--結束container--> 91 </div><!--結束wraper--> 92 <div class="wraper"> 93 <div class="container"> 94 <div class="box1 float">box1</div> 95 <div class="box2">box2</div> 96 </div><!--結束container--> 97 </div><!--結束wraper--> 98 <div class="wraper clearfix"> 99 <div class="container"> 100 <div class="box1">box1</div> 101 <div class="box2 float">box2</div> 102 </div><!--結束container--> 103 </div><!--結束wraper--> 104 <div class="list"> 105 <ol> 106 <li>第一幅圖中,box1與box2在一個綠色的容器中垂直擺放,box1的margin-bottom與box2的margin-top合並,所以它們的margin為20px。</li> 107 <li>第二幅圖中,將綠色容器浮動,浮動之后容器緊緊包裹着里面的元素,是為包裹性。(要體現包裹性,一定不要設置浮動元素的寬度,否則不會自動收縮) 108 </li> 109 <li>第三幅圖中,將box1浮動,box1脫離文檔流,box2向上占據box1的位置,它們的上外邊距沒有合並。<br /> 110 字符“box2”如此顯示是box1的margin-top和margin-right的原因。 111 </li> 112 <li>第四幅圖中,將box2浮動,容器的高度塌陷;box2的上外邊距與box1的下外邊距沒有合並。 113 </li> 114 </ol> 115 </div><!--結束list--> 116 </div><!--結束main--> 117 </body> 118 </html>
深入理解float的破壞性:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>深入理解float的破壞性</title> 6 <style> 7 body { 8 font-size: 16px; 9 line-height: 1.5; 10 } 11 12 .container { 13 width:50%; 14 margin-left: auto; 15 margin-right: auto; 16 } 17 18 .box1,.box2 { 19 background-color: cyan; 20 margin-bottom: 50px; 21 } 22 23 .box1 img,.box2 img { 24 margin:5px; 25 padding:5px; 26 border:1px solid red; 27 } 28 29 .box2 img,.box4 img { 30 float:left; 31 32 } 33 34 .box3 { 35 margin-top: 100px; 36 margin-bottom: 50px; 37 } 38 39 .box3,.box4 { 40 border:2px solid cyan; 41 } 42 43 </style> 44 </head> 45 46 <body> 47 <div class="container"> 48 <div class="box1"> 49 <p>這個盒子中的圖像沒有浮動。我們先來研究一下,圖像在沒有浮動的情況下,為什么會這樣顯示?</p> 50 <p>首先,每一個行內元素都會形成一個行內框,沒有被任何標簽包含的文本被稱為“匿名行內元素”,(文本)行內框的高度為line-height的高度; 51 <img src="http://a.hiphotos.baidu.com/zhidao/pic/item/72f082025aafa40fa38bfc55a964034f79f019ec.jpg" alt="A picture" style="width:140px;height:80px" /> 52 圖像的行內框的高度就是它自身盒子的高度(height+padding+border+margin)。 53 </p> 54 <p>然后,每一行都會形成一個行框,行框必須包含這一行中最高行內框的頂端和最低行內框的底端;於是,這個盒子中的文本和圖像就是這樣顯示了。</p> 55 <p>當所有的行框組合在一起,就形成了整個段落的包含框(containing box,包含盒子)。 56 </div><!--關閉box1--> 57 <div class="box2"> 58 <p>這是第二個盒子,圖像浮動了。</p> 59 <p>如果浮動只是改變了圖像的位置,那么圖像應該依舊與自己所在的那一行文字在同一行上,然而它並沒有。 60 與它在同一行的文本重新形成了行框,這個行框的形成完全忽略了圖像的行內框。也就是說,因為浮動的破壞性,圖像的行內框沒有了。 61 </p> 62 <p>所有的行框組成這個段落的包含框,可以明顯看到,這個段落的包含框沒有把浮動圖像包含在內。</p> 63 <p>總結:浮動的破壞性實際上破壞了浮動元素的高度,浮動元素的高度為0。 64 <p><img src="http://a.hiphotos.baidu.com/zhidao/pic/item/72f082025aafa40fa38bfc55a964034f79f019ec.jpg" alt="A picture" style="width:140px;height:80px" /></p> 65 但是浮動元素是有寬度的,正是因為它有寬度,所以才會有文本環繞效果。</p> 66 </div><!--關閉box2--> 67 <div class="box3"> 68 <img src="http://a.hiphotos.baidu.com/zhidao/pic/item/72f082025aafa40fa38bfc55a964034f79f019ec.jpg" alt="A picture" style="width:140px;height:80px" /> 圖像沒有浮動 69 </div><!--關閉box3--> 70 <div class="box4"> 71 <img src="http://a.hiphotos.baidu.com/zhidao/pic/item/72f082025aafa40fa38bfc55a964034f79f019ec.jpg" alt="A picture" style="width:140px;height:80px" /> 圖像浮動,父元素高度塌陷 72 </div><!--關閉box4--> 73 </div><!--關閉container--> 74 </body> 75 </html>
小tips:
父元素overflow: auto; 可解決浮動元素高度塌陷問題。
將元素浮動前,要設置body元素的margin和padding,以避免各瀏覽器的頁面差異。
5.浮動元素塊狀化。不管元素本身是什么(inline/inline-block/block),只要浮動,自帶display:inline-block聲明。
浮動的規則:
首先,必須了解浮動元素包含塊的概念。
浮動元素的包含塊,是其最近的塊級祖先元素。
規則1:左浮動的元素,左外邊界不能超出其包含塊的左內邊界。(浮動元素不能超出其包含塊的內容區)

規則2:左浮動的元素,左外邊界必須是源文檔中之前出現的左浮動元素的右外邊界;除非后出現的浮動元素的頂端在先出現的浮動元素的底端下面,那么這個后出現的左浮動元素會一直浮動到其包含塊的左內邊界。

規則3:左浮動元素的右外邊界不會與右浮動元素的左外邊界交叉。
(如果兩個浮動元素加起來的寬度大於包含塊的寬度,那么后一個浮動元素將會向下浮動,直到其頂端在前一個浮動元素的底端之下。)

規則4:一個浮動元素的頂端不能超出其包含塊的上內邊界。(浮動元素不能超出其包含塊的內容區)

規則5:浮動元素的頂端不能比它之前所有浮動元素或者塊級元素的頂端更高。

規則6:如果一個段落中有一個浮動圖像,這個圖像的頂端最高只能到該圖像所在行框的頂端。

規則7:如果有多個元素連續浮動,浮動元素不能超出包含塊的內容區,除非某一浮動元素本身寬度就比包含塊的內容區大。
規則8:在滿足以上規則的條件下,浮動元素要浮動得盡可能高、盡可能遠。
關於浮動元素負外邊距:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>浮動元素的margin值</title> 6 <style> 7 * { 8 margin: 0; 9 } 10 11 body { 12 font-size: 16px; 13 line-height: 1.5; 14 } 15 16 .box1,.box2 { 17 width: 500px; 18 margin: 20px auto 50px auto; 19 background-color: cyan; 20 border: 1px solid black; 21 } 22 23 img { 24 border: 1px solid red; 25 float: left; 26 } 27 28 .box1 img { 29 margin: -70px 20px 20px -50px; 30 } 31 32 .box2 img { 33 margin-right: -30px; 34 } 35 36 p { 37 margin: 10px; 38 } 39 40 span { 41 background-color: red; 42 border: 1px solid black; 43 } 44 45 .blockElement { 46 border: 1px solid yellow; 47 background-color: green; 48 margin: 10px; 49 } 50 51 </style> 52 </head> 53 54 <body> 55 <div class="box1"> 56 <img src="http://imgsrc.baidu.com/forum/w%3D580/sign=0c101fe665380cd7e61ea2e59145ad14/f9a3492762d0f7032de1758a08fa513d2797c542.jpg" alt="a picture" style="width:140px;height:210px" /> 57 <p>浮動元素可以設置負外邊距。</p> 58 <p>如果左浮動圖像將左外邊和上外邊距距設為負值,則圖像向左和向上移動相應的距離。</p> 59 <p>此浮動圖像的margin-left為-50px,margin-top為-70px;圖像向左移動了50px的距離,向上移動了70px的距離</p> 60 <p>如果浮動圖像margin負值過大,相應地一部分圖像將會移動到視窗之外(不可見)。</p> 61 <p>浮動圖像可以設置margin值,來控制與周圍文本的距離。</p> 62 <p>此浮動圖像的margin-right為20px,margin-bottom為20px。</p> 63 </div> 64 <div class="box2"> 65 <img src="http://imgsrc.baidu.com/forum/w%3D580/sign=0c101fe665380cd7e61ea2e59145ad14/f9a3492762d0f7032de1758a08fa513d2797c542.jpg" alt="a picture" style="width:140px;height:210px" /> 66 <p>如果左浮動圖像將右外邊距設為負值,那么浮動圖像位置不動,其右邊的文本向左移動相應的距離。</p> 67 <span>如果右邊的文本是行內元素,則其邊框、背景和文字都將在圖像之上顯示;</span> 68 <div class="blockElement">如果右邊的文本是塊級元素,則只有文本會在圖像之上顯示,邊框和背景在圖像之下顯示。</div> 69 </div> 70 </body> 71 </html>
對於定寬的左浮動元素,margin-left為負,元素向左移動;margin-right為負,浮動元素原地不動,其后的行內元素向左移動;兩個都為負,兩種效果結合。
對於不定寬的左浮動元素,margin-left為負,元素的寬度向左擴展;margin-right為負,元素的寬度向右擴展;兩個都為負,向兩邊擴展。
初步結論:只要顯式地設置了width屬性,都是定寬;只有沒有顯式地設置width屬性,才有可能是不定寬。
通過浮動元素負外邊距實現不改變DOM結構的流體布局:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>不改變DOM結構的流體布局</title> 6 <style> 7 .container { 8 width:700px; 9 margin: 50px auto; 10 background-color: orange; 11 font-size: 16px; 12 line-height: 1.5; 13 } 14 15 .box1 { 16 width:100%; 17 float:left; 18 } 19 20 img { 21 float: left; 22 margin-left: -200px; 23 } 24 25 .box2 { 26 margin-right: 230px; 27 } 28 29 .clearfix:after { 30 content: ""; 31 display: table; 32 clear: both; 33 } 34 35 .clearfix { 36 *zoom: 1; 37 } 38 39 h3,p { 40 padding-left: 10px; 41 } 42 43 </style> 44 </head> 45 <body> 46 <div class="container clearfix"> 47 <div class="box1"> 48 <div class="box2"> 49 <h3>不改變DOM位置的流體布局</h3> 50 <p>假如有一段文本和一幅圖像,在DOM節點中,文本在前,圖像在后,怎么能把圖像定位到右邊呢?</p> 51 <p>通常的做法是,調換DOM節點中圖像與文本的位置,讓圖像在前,文本在后,然后將圖像浮動到右邊即可。</p> 52 <p>但這樣改變DOM節點順序始終不妥,還有什么更好的方法呢?</p> 53 <p>下面就介紹一種新的思路來完成布局。</p> 54 <ul> 55 <li>將文本用div包起來,定義為box1;現在的結構是一個box1和一個img。</li> 56 <li>將box1寬度設為100%,左浮動;將img設置一個寬度,也左浮動,然后margin-left設為負的寬度值;此時圖像就定位到文本的右邊啦。 57 (或者,將box1的寬度設為100%,左浮動,並且margin-right為負的圖像寬度;圖像也會定位到文本右邊。)</li> 58 <li>但是有一個問題,圖像蓋住了文本內容,這可怎么辦?</li> 59 <li>重點來了,在box1中增加一個box2,box2把文本全部包起來,然后margin-right設為圖像的寬度(+額外的間距),這樣就解決問題啦!</li> 60 </ul> 61 </div><!--關閉box2--> 62 </div><!--關閉box1--> 63 <img src="http://imgsrc.baidu.com/forum/w%3D580/sign=0c101fe665380cd7e61ea2e59145ad14/f9a3492762d0f7032de1758a08fa513d2797c542.jpg" alt="a picture" style="width:200px;height:300px" /> 64 </div><!--關閉container--> 65 </body> 66 </html>
想一下我們是如何將圖像從文本的下面定位到文本的右邊的?
第一種方法,文本寬度100%,左浮動,圖像自身寬度,也左浮動;可以這樣想,如果視窗的寬度足夠,兩個相鄰的浮動元素本應該是緊挨着的,后浮動的圖像開啟了margin負值位移技能,向左邊移動,當它向左移動的距離等於或者大於自身寬度,它整個圖像都將會覆蓋在文本之上。
第二種方法,文本寬度100%,左浮動,margin-right為負值;可以這樣理解,普通流中,文本占據一整行的寬度,但是可以通過margin調整它在普通流中所占的空間,當margin為正,所占的空間向外邊擴展,當margin為負,所占的空間向里面收縮;當margin-right為負的圖像寬度時,文本右側收縮出來的寬度剛好夠圖形容身。
