宏觀地講,咱們的web頁面和photoshop等設計軟件有本質的區別:web頁面的製做,是個「流」,必須從上而下,像「織毛衣」。而設計軟件,想往哪裏畫個東西,都能畫。html
咱們來看看標準流有哪些微觀現象。前端
(1)空白摺疊現象:git
不管多少個空格、換行、tab,都會摺疊爲一個空格。github
好比,若是咱們想讓img標籤之間沒有空隙,必須緊密鏈接:web
<img src="images/0.jpg" /><img src="images/1.jpg" /><img src="images/2.jpg" />
(2)高矮不齊,底邊對齊:面試
舉例以下:瀏覽器
(3)自動換行,一行寫不滿,換行寫。微信
學習的初期,咱們就要知道,標準文檔流等級森嚴。標籤分爲兩種等級:佈局
咱們能夠舉一個例子,看看塊級元素和行內元素的區別:
上圖中能夠看到,h1
標籤是塊級元素,佔據了整行,span
標籤是行內元素,只佔據內容這一部分。
如今咱們嘗試給兩個標籤設置寬高。效果以下:
上圖中,咱們嘗試給兩個標籤設置寬高,但發現,寬高屬性只對塊級元素h1
生效。因而咱們能夠作出以下總結。
行內元素和塊級元素的區別:(很是重要)
行內元素:
塊級元素:
塊級元素和行內元素的分類:
在之前的HTML知識中,咱們已經將標籤分過類,當時分爲了:文本級、容器級。
從HTML的角度來說,標籤分爲:
PS:爲甚麼說p是文本級標籤呢?由於p裏面只能放文字&圖片&表單元素,p裏面不能放h和ul,p裏面也不能放p。
如今,從CSS的角度講,CSS的分類和上面的很像,就p不同:
行內元素:除了p以外,全部的文本級標籤,都是行內元素。p是個文本級,可是是個塊級元素。
塊級元素:全部的容器級標籤都是塊級元素,還有p標籤。
咱們把上面的分類畫一個圖,便可一目瞭然:
咱們能夠經過display
屬性將塊級元素和行內元素進行相互轉換。display即「顯示模式」。
一旦,給一個塊級元素(好比div)設置:
display: inline;
那麼,這個標籤將當即變爲行內元素,此時它和一個span無異。inline就是「行內」。也就是說:
舉例以下:
一樣的道理,一旦給一個行內元素(好比span)設置:
display: block;
那麼,這個標籤將當即變爲塊級元素,此時它和一個div無異。block」是「塊」的意思。也就是說:
舉例以下:
標準流裏面的限制很是多,致使不少頁面效果沒法實現。若是咱們如今就要並排、而且就要設置寬高,那該怎麼辦呢?辦法是:移民!脫離標準流!
css中一共有三種手段,使一個元素脫離標準文檔流:
這便引出咱們今天要講的內容:浮動。
浮動是css裏面佈局用的最多的屬性。
如今有兩個div,分別設置寬高。咱們知道,它們的效果以下:
此時,若是給這兩個div增長一個浮動屬性,好比float: left;
,效果以下:
這就達到了浮動的效果。此時,兩個元素並排了,而且兩個元素都可以設置寬度、高度了(這在上一段的標準流中,不能實現)。
浮動想學好,必定要知道三個性質。接下來說一講。
脫標即脫離標準流。咱們來看幾個例子。
證實1:
上圖中,在默認狀況下,兩個div標籤是上下進行排列的。如今因爲float屬性讓上圖中的第一個<div>
標籤出現了浮動,因而這個標籤在另一個層面上進行排列。而第二個<div>
還在本身的層面上聽從標準流進行排列。
證實2:
上圖中,一個span標籤不須要轉成塊級元素,就可以設置寬度、高度了。因此可以證實一件事兒,就是全部標籤已經不區分行內、塊了。也就是說,一旦一個元素浮動了,那麼,將可以並排了,而且可以設置寬高了。不管它原來是個div仍是個span。
咱們來看一個例子就明白了。
咱們給三個div均設置了float: left;
屬性以後,而後設置寬高。當改變瀏覽器窗口大小時,能夠看到div的貼靠效果:
上圖顯示,3號若是有足夠空間,那麼就會靠着2號。若是沒有足夠的空間,那麼會靠着1號大哥。
若是沒有足夠的空間靠着1號大哥,3號本身去貼左牆。
不過3號本身去貼牆的時候,注意:
上圖顯示,3號貼左牆的時候,並不會往1號裏面擠。
一樣,float還有一個屬性值是right
,這個和屬性值left
是對稱的。
來看一張圖就明白了。咱們讓div浮動,p不浮動。
上圖中,咱們發現:div擋住了p,但不會擋住p中的文字,造成「字圍」效果。
關於浮動咱們要強調一點,浮動這個東西,爲避免混亂,咱們在初期必定要遵循一個原則:永遠不是一個東西單獨浮動,浮動都是一塊兒浮動,要浮動,你們都浮動。
收縮:一個浮動的元素,若是沒有設置width,那麼將自動收縮爲內容的寬度(這點很是像行內元素)。
舉例以下:
上圖中,div自己是塊級元素,若是不設置widh,它會單獨霸佔整行;可是,設置div浮動後,它會收縮
上圖所示,將para1和para2設置爲浮動,它們是div的兒子。此時para1+para2的寬度小於div的寬度。效果如上圖所示。可若是設置para1+para2的寬度大於div的寬度,咱們會發現,para2掉下來了:
佈置一個做業,要求實現下面的效果:
爲實現上方效果,代碼以下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>Document</title> <style type="text/css"> *{ margin: 0; padding: 0; } .header{ width: 970px; height: 103px; /*居中。這個語句的意思是:居中:*/ margin: 0 auto; } .header .logo{ float: left; width: 277px; height: 103px; background-color: red; } .header .language{ float: right; width: 137px; height: 49px; background-color: green; margin-bottom: 8px; } .header .nav{ float: right; width: 679px; height: 46px; background-color: green; } .content{ width: 970px; height: 435px; /*居中,這個語句今天沒講,你照抄,就是居中:*/ margin: 0 auto; margin-top: 10px; } .content .banner{ float: left; width: 310px; height: 435px; background-color: gold; margin-right: 10px; } .content .rightPart{ float: left; width: 650px; height: 435px; } .content .rightPart .main{ width: 650px; height: 400px; margin-bottom: 10px; } .content .rightPart .links{ width: 650px; height: 25px; background-color: blue; } .content .rightPart .main .news{ float: left; width: 450px; height: 400px; } .content .rightPart .main .hotpic{ float: left; width: 190px; height: 400px; background-color: purple; margin-left: 10px; } .content .rightPart .main .news .news1{ width: 450px; height: 240px; background-color: skyblue; margin-bottom: 10px; } .content .rightPart .main .news .news2{ width: 450px; height: 110px; background-color: skyblue; margin-bottom: 10px; } .content .rightPart .main .news .news3{ width: 450px; height: 30px; background-color: skyblue; } .footer{ width: 970px; height: 35px; background-color: pink; /*沒學,就是居中:*/ margin: 0 auto; margin-top: 10px; } </style> </head> <body> <!-- 頭部 --> <div class="header"> <div class="logo">logo</div> <div class="language">語言選擇</div> <div class="nav">導航條</div> </div> <!-- 主要內容 --> <div class="content"> <div class="banner">大廣告</div> <div class="rightPart"> <div class="main"> <div class="news"> <div class="news1"></div> <div class="news2"></div> <div class="news3"></div> </div> <div class="hotpic"></div> </div> <div class="links"></div> </div> </div> <!-- 頁尾 --> <div class="footer"></div> </body> </html>
其實,這個頁面的佈局是下面這個網站:
這裏所說的清除浮動,指的是清除浮動與浮動之間的影響。
經過上面這個例子,咱們發現,此例中的網頁就是經過浮動實現並排的。
好比說一個網頁有header、content、footer這三部分。就拿content部分來舉例,若是設置content的兒子爲浮動,可是,這個兒子又是一個全新的標準流,因而兒子的兒子仍然在標準流裏。
從學習浮動的第一天起,咱們就要明白,浮動有開始,就要有清除。咱們先來作個實驗。
下面這個例子,有兩個塊級元素div,div沒有任何屬性,每一個div裏有li,效果以下:
上面這個例子很簡單。可若是咱們給裏面的<li>
標籤加浮動。效果卻成了下面這個樣子:
代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> *{ } li{ float: left; width: 100px; height: 20px; background-color: pink; } </style> </head> <body> <div class="box1"> <ul> <li>生命壹號1</li> <li>生命壹號2</li> <li>生命壹號3</li> <li>生命壹號4</li> </ul> </div> <div class="box2"> <ul> <li>許嵩1</li> <li>許嵩2</li> <li>許嵩3</li> <li>許嵩4</li> </ul> </div> </body> </html>
效果以下:
上圖中,咱們發現:第二組中的第1個li,去貼靠第一組中的最後一個li了(咱們本覺得這些li會分紅兩排)。
這便引出咱們要講的:清除浮動的第一種方式。
那該怎麼解決呢?
形成前言中這個現象的根本緣由是:li的父親div沒有設置高度,致使這兩個div的高度均爲0px(咱們能夠經過網頁的審查元素進行查看)。div的高度爲零,致使不能給本身浮動的孩子,撐起一個容器。
撐不起一個容器,致使本身的孩子沒辦法在本身的內部進行正確的浮動。
好,如今就算給這個div設置高度,可若是div本身的高度小於孩子的高度,也會出現不正常的現象:
給div設置一個正確的合適的高度(至少保證高度大於兒子的高度),就能夠看到正確的現象:
總結:
若是一個元素要浮動,那麼它的祖先元素必定要有高度。
有高度的盒子,才能關住浮動。(記住這句過來人的經驗之語)
只要浮動在一個有高度的盒子中,那麼這個浮動就不會影響後面的浮動元素。因此就是清除浮動帶來的影響了。
網頁製做中,高度height其實不多出現。爲何?由於能被內容撐高!也就是說,剛剛咱們講解的方法1,工做中用得不多。
那麼,能不能不寫height,也把浮動清除了呢?也讓浮動之間,互不影響呢?
這個時候,咱們可使用clear:both;
這個屬性。以下:
clear:both;
clear就是清除,both指的是左浮動、右浮動都要清除。意思就是:清除別人對個人影響。
這種方法有一個很是大的、致命的問題,它所在的標籤,margin屬性失效了。讀者能夠試試看。
margin失效的本質緣由是:上圖中的box1和box2,高度爲零。
上面這個例子中,爲了防止第二個div貼靠到第二個div,咱們能夠在這兩個div中間用一個新的div隔開,而後給這個新的div設置clear: both;
屬性。既然這個新的div沒法設置margin屬性,咱們能夠給它設置height,以達到margin的效果(曲線救國)。這即是隔牆法。
咱們看看例子效果就知道了:
上圖這個例子就是隔牆法。
內牆法:
近些年,有演化出了「內牆法」:
上面這個圖很是重要,看成內牆法的公式,先記下來。
爲了講內牆法,咱們先記住一句重要的話:一個父親是不能被浮動的兒子撐出高度的。舉例以下:
(1)咱們在一個div裏放一個有寬高的p,效果以下:(很簡單)
(2)可若是在此基礎之上,給p設置浮動,卻發現父親div沒有高度了:
(3)此時,我麼能夠在div的裏面放一個div(做爲內牆),就可讓父親div恢復高度:
因而,咱們採用內牆法解決前言中的問題:
與外牆法相比,內牆法的優點(本質區別)在於:內牆法能夠給它所在的家撐出寬度(讓box1有高)。即:box1的高度能夠自適應內容。
而外牆法,雖然一道牆能夠把兩個div隔開,可是這兩個div沒有高,也就是說,沒法wrap_content。
咱們可使用以下屬性:
overflow:hidden;
overflow即「溢出」, hidden即「隱藏」。這個屬性的意思是「溢出隱藏」。顧名思義:全部溢出邊框的內容,都要隱藏掉。以下:
上圖顯示,overflow:hidden;
的本意是清除溢出到盒子外面的文字。可是,前端開發工程師發現了,它能作偏方。以下:
一個父親不能被本身浮動的兒子,撐出高度。可是,只要給父親加上overflow:hidden
; 那麼,父親就能被兒子撐出高了。這是一個偏方。
舉個例子:
那麼對於前言中的例子,咱們一樣可使用這一屬性:
咱們在上一段講了四種清除浮動的方法,本段來進行一個總結。
浮動的元素,只能被有高度的盒子關住。 也就是說,若是盒子內部有浮動,這個盒子有高,那麼妥妥的,浮動不會互相影響。
工做上,咱們絕對不會給全部的盒子加高度,這是由於麻煩,而且不能適應頁面的快速變化。
<div> //設置height <p></p> <p></p> <p></p> </div> <div> //設置height <p></p> <p></p> <p></p> </div>
clear:both;
法最簡單的清除浮動的方法,就是給盒子增長clear:both;表示本身的內部元素,不受其餘盒子的影響。
<div> <p></p> <p></p> <p></p> </div> <div> //clear:both; <p></p> <p></p> <p></p> </div>
浮動確實被清除了,不會互相影響了。可是有一個問題,就是margin失效。兩個div之間,沒有任何的間隙了。
在兩部分浮動元素中間,建一個牆。隔開兩部分浮動,讓後面的浮動元素,不去追前面的浮動元素。
牆用本身的身體當作了間隙。
<div> <p></p> <p></p> <p></p> </div> <div class="cl h10"></div> <div> <p></p> <p></p> <p></p> </div>
咱們發現,隔牆法好用,可是第一個div,仍是沒有高度。若是咱們如今想讓第一個div,自動根據本身的兒子撐出高度,咱們就要想一些「小伎倆」。
內牆法:
<div> <p></p> <p></p> <p></p> <div class="cl h10"></div> </div> <div> <p></p> <p></p> <p></p> </div>
內牆法的優勢就是,不只僅可以讓後部分的p不去追前部分的p了,而且能把第一個div撐出高度。這樣,這個div的背景、邊框就可以根據p的高度來撐開了。
overflow:hidden;
這個屬性的本意,就是將全部溢出盒子的內容,隱藏掉。可是,咱們發現這個東西可以用於浮動的清除。
咱們知道,一個父親,不能被本身浮動的兒子撐出高度,可是,若是這個父親加上了overflow:hidden;那麼這個父親就可以被浮動的兒子撐出高度了。這個現象,不能解釋,就是瀏覽器的偏方。
而且,overflow:hidden;可以讓margin生效。
清除浮動的例子:
咱們如今舉個例子,要求實現下圖中無序列表部分的效果:
對比一下咱們講的四種清除浮動的方法。若是用外牆法,ul中不能插入div標籤,由於ul中只能插入li,若是插入li的牆,會浪費語義。若是用內牆法,不美觀。綜合對比,仍是用第四種方法來實現吧,這會讓標籤顯得極其乾淨整潔:
上方代碼中,若是沒有加overflow:hidden;
,那麼第二行的li會緊跟着第一行li的後面。
講一下上述知識點涉及到的瀏覽器兼容問題。
兼容性的第一條:IE6不支持小於12px的盒子,任何小於12px的盒子,在IE6中看都大。即:IE 6不支持微型盒子。
舉個例子。咱們設置一個height爲 5px 、寬度爲 200px的盒子,看下在IE 8和 IE 6中的顯示效果:
解決辦法很簡單,就是將盒子的字號大小,設置爲小於盒子的高,好比,若是盒子的高爲5px,那就把font-size設置爲0px(0px < 5px)。以下:
height: 5px; _font-size: 0px;
咱們如今介紹一下瀏覽器hack。hack就是「黑客」,就是使用瀏覽器提供的後門,針對某一種瀏覽器作兼容。
IE6留了一個後門:只要給css屬性以前,加上下劃線,這個屬性就是IE6的專有屬性。
好比說,咱們給背景顏色這個屬性加上下劃線,就變成了_background-color: green;
。效果以下:
因而乎,爲了解決微型盒子(即height小於12px)的問題,正確寫法:(注意不要忘記下劃線)
height: 10px; _font-size:0;
兼容性的第二條:IE6不支持用overflow:hidden;
來清除浮動。
解決辦法,以毒攻毒。追加一條:
_zoom:1;
完整寫法:
overflow: hidden; _zoom:1;
實際上,_zoom:1;
可以觸發瀏覽器hasLayout機制。這個機制,不要深究了,由於只有IE6有。咱們只須要讓IE6好用,具體的實現機制,能夠自行查閱。
須要強調的是,overflow:hidden;
的本意,就是讓溢出盒子的border的內容隱藏,這個功能是IE6兼容的。不兼容的是overflow:hidden;
清除浮動的時候。
總結:
咱們剛纔學習的兩個IE6的兼容問題,都是經過多寫一條hack來解決的,這個咱們稱爲伴生屬性,即兩個屬性,要寫一塊兒寫。
屬性1:
height:6px; _font-size:0;
屬性2:
overflow:hidden; _zoom:1;
咱們來說一下浮動中和margin相關的知識。
標準文檔流中,豎直方向的margin不疊加,以較大的爲準(水平方向的margin是能夠疊加的,即水平方向沒有塌陷現象)。以下圖所示:
若是不在標準流,好比盒子都浮動了,那麼兩個盒子之間是沒有塌陷現象的。
margin:0 auto;
margin的值能夠爲auto,表示自動。當left、right兩個方向都是auto的時候,盒子居中了:
margin-left: auto; margin-right: auto;
盒子居中的簡寫爲:
margin:0 auto;
對上方代碼的理解:上下的margin爲0,左右的margin都儘量的大,因而就居中了。
注意:
margin:0 auto;
的盒子,必須有width,有明確的width。(能夠這樣理解,若是沒有明確的witdh,那麼它的witdh就是霸佔整行,沒有意義)margin:0 auto;
居中。也就是說,當一個盒子浮動了、絕對定位了、固定定位了,都不能使用margin:0 auto;margin:0 auto;
是讓盒子居中,不是讓盒子裏的文本居中。文本的居中,要使用text-align:center;
對上面的第三條總結一下:
margin:0 auto; //讓這個div本身在大容器中居中。 text-align: center; //讓這個div內部的文本居中。
順便普及一下知識,text-align還有:
text-align:left; //沒啥用,由於默認居左 text-align:right; //文本居右
咱們來看一個奇怪的現象。如今有下面這樣一個結構:(div中放一個p)
<div> <p></p> </div>
上面的結構中,咱們嘗試經過給兒子p
一個margin-top:50px;
的屬性,讓其與父親保持30px的上邊距。結果卻看到了下面的奇怪的現象:
此時咱們給父親div加一個border屬性,就正常了:
若是父親沒有border,那麼兒子的margin實際上踹的是「流」,踹的是這「行」。因此,父親總體也掉下來了。
margin這個屬性,本質上描述的是兄弟和兄弟之間的距離; 最好不要用這個marign表達父子之間的距離。
因此,若是要表達父子之間的距離,咱們必定要善於使用父親的padding,而不是兒子的margin。
當出現連續浮動的元素,攜帶與浮動方向相同的margin時,隊首的元素,會雙倍marign。
<ul> <li></li> <li></li> <li></li> </ul>
解決方案:
(1)使浮動的方向和margin的方向,相反。
因此,你就會發現,咱們特別喜歡,浮動的方向和margin的方向相反。而且,前端開發工程師,把這個當作習慣了。
float: left; margin-right: 40px;
(2)使用hack:(不必,別慣着這個IE6)
單獨給隊首的元素,寫一個一半的margin:
<li class="no1"></li>
ul li.no1{ _margin-left:20px; }
PS:雙倍margin的問題,面試常常問哦。
解決辦法:不用管,由於根本就不容許用兒子踹父親(即描述父子之間的距離,請用padding,而不是margin)。因此,若是你出現了3px bug,說明你的代碼不標準。
IE6,千萬不要跟他死坑、較勁,它不配。 格調要高,咱們講IE6的兼容性問題,就是爲了增長面試的成功率,不是爲了成爲IE6的專家。
想學習代碼以外的軟技能?不妨關注個人微信公衆號:生命團隊(id:vitateam
)。
掃一掃,你將發現另外一個全新的世界,而這將是一場美麗的意外: