在CSS網頁開發布局中,需要對浮動和定位有深刻的理解才能在開發中游刃有余。
基於此,在博客園中做了本篇總結,這些總結來自實踐經驗和閱讀一些書籍後的理解總結,主要內容為浮動,清除浮動,定位。
(可點擊屏幕左邊的目錄查閱)
首先簡單布局一下,代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>css Test</title> <style type="text/css"> #bigBox { border: 2px solid Gray; width: 500px; height: 400px; margin: 100px auto; } #box1{ background: yellow; width: 100px; height: 100px; } #box2{ background: SkyBlue; width: 120px; height: 100px; } #box3{ background: pink; width: 140px; height: 100px; } </style> </head> <body> <div id="bigBox"> <div id="box1">1</div> <div id="box2">2</div> <div id="box3">3</div> </div> </body> </html>
效果圖:
圖p1
脫離文檔流,即在元素原來的位置中脫離出來,可以理解為漂浮起來,但是要注意一些細節。
若浮動元素後面有不浮動的元素,那麼其後面不浮動的元素會把浮動元素視為消失,然後頂到它的位置中。
我們來測試一下:對第二個div(id=box2)設置浮動,觀察第三個div的位置
#box1{ background: yellow; width: 100px; height: 100px; } #box2{ background: SkyBlue; width: 120px; height: 100px; float:left;/*測試內容*/ } #box3{ background: pink; width: 140px; height: 100px; }
效果圖:
圖p2
我們可以看到第三個div頂到浮動div原來的位置上去了,這裡的float:left 設置為right,也同樣,即第二個div消失了,後面的頂上去。
效果圖:
圖p3
我們不能理解為設置float之後,這個元素就完全漂浮在沒有設置float元素的上面,雖然在細節一中的效果圖中看是漂浮在上面(2在3的上面)。這個細節就是浮動只對後面的元素造成影響(所謂影響,就是後面的元素把它視為消失),對於排在它前面的同級塊元素,不會對其位置造成影響。(即如果前面的同級塊元素沒有設置浮動,那麼它也不會漂浮到這個元素的上面)。細節一的p1例子已經驗證了這一特性(2還是在1的下面)。
那麼,對於排在前面的同級內聯元素呢?對於同級內聯元素,設置了float屬性的元素與前面的內聯元素屬於同一層面,而且優先級高於前面的同級內聯元素,這裡的優先級指位置優先級,比如float:left,那麼前面的內聯元素如果原來占據最左邊,那麼它由於優先級低於浮動元素,所以它就會讓位與浮動元素,排在浮動元素的右邊。
我們來看一下測試代碼(重點查看注釋的測試內容):
#box1{ background: yellow; width: 100px; height: 100px; display: inline-block; /*測試內容*/ } #box2{ background: SkyBlue; width: 120px; height: 100px; float:left; /*測試內容*/ } #box3{ background: pink; width: 140px; height: 100px; }
效果圖:
圖p4
分析:對於1(這裡用數字代表相應的div,上下同)來說,由於排在浮動的2的前面,所以它無論是否為塊元素,都和2屬於同一層面,再由於它不是塊元素,所以它的位置優先級別低於2,由於2的float:left,向左浮動,所以它靠最左,1被擠到它的右邊。對於3來說,2由於是浮動,所以視為消失了,但是由於3是塊元素,所以獨占一行,於是就有了上面的效果。
文字永遠會被擠出。我們把1,2設置浮動,把3注釋,然後添加p標簽。查看一下情況:
<div id="bigBox"> <div id="box1">1</div> <div id="box2">2</div> <!-- <div id="box3">3</div> --> <p>HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! HelloWorld! 10個HelloWorld!</p> </div>
圖p5
實際上,並不是P元素和1,2浮動元素並列排在了一起,在細節一二中,我們知道p元素一定是頂到1的位置中的,但是由於文字永遠是被擠出來的,所以他們被擠到2的左邊,此時實現了一個文字環繞效果。我們可以給P元素添加背景色來查看一下實際:
p { background-color: red; }
圖p6
同樣的,父元素屬於文檔流,如果子元素中有設置浮動的,那麼也視為消失,所以父元素不會包裹它,如果全部子元素都為浮動,那麼相當於這個父元素裡面沒有子元素,此時的表現和子元素為空一樣。
我們先來看一下,在沒有浮動元素的文檔流中的情況:
代碼:
body { margin: 0 300px; } #bigBox { border: 2px solid Gray; /* width: 500px; height: 400px;*//*測試內容:這裡要設置去掉寬高*/ margin: 100px auto; } #box1{ background: yellow; width: 100px; height: 100px; } #box2{ background: SkyBlue; width: 120px; height: 100px; } #box3{ background: pink; width: 140px; height: 100px; }
<body> <div id="bigBox"> <div id="box1">1</div> <div id="box2">2</div> <div id="box3">3</div> </div> </body>
效果圖:
圖p7
這裡的div(id=bigBox,1,2,3的父級元素)沒有設置寬高,所以自動支撐起了子元素的寬高,由於1,2,3都是塊元素,所以獨占一行,寬度自動適應為body的寬度,所以如效果圖所示,這是沒有設置浮動的情況。
我們把2設置為浮動,查看一下效果:
#box2{ background: SkyBlue; width: 120px; height: 100px; float: left; /*測試內容*/ }
效果圖:
圖p8
父元素還是可以適應,不過視2為消失。
下面我們把全部子元素都設置為浮動,查看一下效果:
body { margin: 0 300px; } #bigBox { border: 2px solid Gray; /* width: 500px; height: 400px;*/ margin: 100px auto; } #box1{ background: yellow; width: 100px; height: 100px; float: left; /*測試內容*/ } #box2{ background: SkyBlue; width: 120px; height: 100px; float: left; /*測試內容*/ } #box3{ background: pink; width: 140px; height: 100px; float:left; /*測試內容*/ }
圖p9
我們把1,2,3去掉,查看沒有子元素的父元素的效果圖,然後對比一下:
<body> <div id="bigBox"> <!-- <div id="box1">1</div> <div id="box2">2</div> <div id="box3">3</div> --> </div> </body> </html>
圖p10
結果和p9是一樣的,也就是p9中父元素把1,2,3視為消失了。
clear屬性值有left,right,both,一般情況下對使用both清除浮動,我們來看一下:
#box1{ background: yellow; width: 100px; height: 100px; } #box2{ background: SkyBlue; width: 120px; height: 100px; float: left; /*測試內容*/ } #box3{ background: pink; width: 140px; height: 100px; clear:both; /*測試內容*/ }
圖p11
請對比p2,可以這樣形象理解,把原來2的消失變成了可見,然後就排在它的後面。
<div id="bigBox"> <div id="box1">1</div> <div id="box2">2</div> <div id="clear"></div> <!-- 測試內容 --> <div id="box3">3</div> </div>
#clear { clear: both; }
同樣可以達到預期效果:
圖p12
圖p7中我們看到父元素把子元素1,2,3視為消失,所以無法自適應子元素的寬度,為了消除子元素浮動對父元素的影響,這裡有三個方法可以解決問題,我們來測試分析一下。
先把父元素受影響的代碼和效果圖貼出來:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>css Test</title> <style type="text/css"> body { margin: 0 300px; } #bigBox { border: 2px solid Gray; /* width: 500px; height: 400px;*/ margin: 100px auto; /*clear: both;*/ } #box1{ background: yellow; width: 100px; height: 100px; float: left; /*測試內容*/ } #box2{ background: SkyBlue; width: 120px; height: 100px; float: left; /*測試內容*/ } #box3{ background: pink; width: 140px; height: 100px; float: left; /*測試內容*/ } #clear { clear: both; } </style> </head> <body> <div id="bigBox"> <div id="box1">1</div> <div id="box2">2</div> <div id="box3">3</div> </div> </body> </html>View Code
圖p13
<div id="bigBox"> <div id="box1">1</div> <div id="box2">2</div> <div id="box3">3</div> <!-- 這是一個清除浮動的空標簽 --> <div id="clear"></div> </div>
效果圖:
圖p14
分析:原理很簡單,空div設置了clear屬性,所以它不受前面1,2,3的影響,所以它就會排在1,2,3的後面,造成了空div與頂部之間有了一定的距離,這個距離就拉大了父元素的尺寸,所以從表現上看,就像是清除了浮動,達到我們想要的效果。
此方法的弊端就是添加了額外的無意義的標簽。
#bigBox { border: 2px solid Gray; /* width: 500px; height: 400px;*/ margin: 100px auto; overflow:hidden; /*測試內容*/ }
效果圖:
圖p15
overflow的屬性值有:visible(默認值),hidden,scroll,auto,inherit
常用的是hidden屬性,除了visible之外,不算inherit(繼承)在內的其他三個屬性值,如果設置了,那麼該元素就會與浮動元素在同一個層面。我們可以看到文章開頭的圖p2中,2浮動在3的上面,因為它們不在同一個層面,如果對3設置overflow:hidden;(三個屬性都可),那麼他們就屬於同一個層面,此時3雖然受浮動的影響,但是由於同一個層面的關系,所以它排在了2的後面,我們來測試一下。
#box1{ background: yellow; width: 100px; height: 100px; } #box2{ background: SkyBlue; width: 120px; height: 100px; float: left; /*測試內容*/ } #box3{ background: pink; width: 140px; height: 100px; overflow: hidden;/*測試內容*/ }
效果圖:
圖p16
我們比較圖p2和p16,就可以看出overflow的這一特性。
回到我們討論的父元素上面,父元素設置overflow屬性,所以它就與所有浮動的子元素在同一層面上,所以就支撐了起來。不過它的弊端就是overflow的三個屬性會對子元素超出父元素的部分不顯示出來,可能造成信息缺失。
在ie6及以下版本中(怪異模式),overflow的設置還是不起作用,這裡就要用到ie特有的一個屬性zoom來解決,只要設置zoom:1,即原來的大小即可,代碼如下:
#bigBox { border: 2px solid Gray; /* width: 500px; height: 400px;*/ margin: 100px auto; overflow: hidden; zoom:1;/*添加這個屬性,可兼容ie6*/ }
這是最實用和推薦的方法,一般把這個偽類的名稱設置為 -XXX-clearFix,比如新浪微博就是用 -weibo-clearFix,在使用的過程中,我們習慣性的使用偽對象after的方法,在clearFix後面添加一些清除浮動的屬性。
.-test-clearFix:after { clear: both; display: block; visibility: hidden; /*設置不可見*/ height: 0; line-height: 0; content: ""; /*after偽對象必須的屬性,可以設置內容為空*/ } .-test-clearFix {}
在父級div裡面添加這個類即可:
<div id="bigBox" class="-test-clearFix"> <div id="box1">1</div> <div id="box2">2</div> <div id="box3">3</div> </div>
效果圖:
圖p17
相對自身偏移。
相對定位比較好理解,它相對於自身進行了定位,所設置的偏移屬性的參照物為本身原來的位置。
元素原來的位置不脫離文檔流,占據了位置。
對於特點一、二,我們來測試一下:
#bigBox { border: 2px solid Gray; width: 500px; height: 400px; margin: 100px auto; } #box1{ background: yellow; width: 100px; height: 100px; float: left; } #box2{ background: SkyBlue; width: 120px; height: 100px; float: left; position: relative;/*測試內容*/ top: -140px; } #box3{ background: pink; width: 140px; height: 100px; float: left; }
圖p18
2占據了原來的位置,所以3不會靠左移動。
脫離文檔流
絕對定位和float屬性有相似之處,設置了這個屬性的元素會脫離文檔流,脫離文檔流後的表現和float一樣,但是它無法清除浮動也不占據位置。
#bigBox { border: 2px solid Gray; /* width: 500px; height: 400px;*/ margin: 100px auto; position: relative; /*測試內容*/ } #box1{ background: yellow; width: 100px; height: 100px; position: absolute;/*測試內容*/ } #box2{ background: SkyBlue; width: 120px; height: 100px; position: absolute; /*測試內容*/ } #box3{ background: pink; width: 140px; height: 100px; position: absolute; /*測試內容*/ }
效果圖:
圖p19
圖中可以看出1,2,3進行了絕對定位,並且重疊在了一起。其重疊特性為下面的特點二。
排再文檔流後面的絕對定位元素顯示的優先級高於前面的絕對定位元素。
為了區分,我們來給出一定的位移,觀察前後優先級:
#bigBox { border: 2px solid Gray; /* width: 500px; height: 400px;*/ margin: 100px auto; position: relative; /*測試內容*/ } #box1{ background: yellow; width: 100px; height: 100px; position: absolute;/*測試內容*/ } #box2{ background: SkyBlue; width: 120px; height: 100px; position: absolute; /*測試內容*/ left: 50px; top:40px; } #box3{ background: pink; width: 140px; height: 100px; position: absolute; /*測試內容*/ left: 80px; top: 20px; }
圖p20
圖中可以看出優先級 3>2>1
絕對定位,其父級元素如果沒有設置定位屬性,則以更高級別的有設置定位屬性的作為參照物進行定位,如果父級元素都沒有定位屬性,則以body作為參照。
(代碼參考"特點一"中的代碼#bigBox裡面,設置了relative屬性,裡面的1,2,3以該父級元素進行絕對定位)
這個定位屬性是最簡單的,其特點是脫離文檔流,不占據位置,然後固定在屏幕,不會對文檔流造成影響。這裡就不進行代碼驗證。
深入理解了這些屬性,就可以在實際工作中靈活應用,後續會總結一些布局實戰。本文若有不妥之處,歡迎批評指正。