因爲沒有找到本身認爲完整的關於普通流、浮動和絕對定位的中文文章,因而鼓起勇氣決定本身來寫篇。css
在普通流中的 Box(框) 屬於一種 formatting context(格式化上下文) ,類型能夠是 block ,或者是 inline ,但不能同時屬於這二者。而且, Block boxes(塊框) 在 block formatting context(塊格式化上下文) 裏格式化, Inline boxes(塊內框) 則在 inline formatting context(行內格式化上下文) 裏格式化。工具
咱們知道,任何被渲染的元素都屬於一個 box ,而且不是 block ,就是 inline 。即便是未被任何元素包裹的文本,根據不一樣的狀況,也會屬於匿名的 block boxes 或者 inline boxes。因此上面的描述,便是把全部的元素劃分到對應的 formatting context 裏。佈局
組合上面的定義,而且姑且先把 formatting context 看作是一種範圍限定,那麼具體講,普通流就是這樣的過程:code
1.在對應的 block formatting context 中,塊級元素按照其在HTML中的順序,在其容器框裏從左上角開始,從上到下垂直地依次分配空間、堆砌( stack ),並獨佔一行,邊界緊貼父容器。兩相鄰元素間的距離由 margin 屬性決定,在同一個 block formatting context 中的垂直邊界將被重疊( collapse )。而且,除非建立一個新的 block formatting context ,不然塊級元素的寬度不受浮動元素的影響(這就是浮動元素能蓋在塊級元素上面的緣由)。orm
2.在對應的 inline formatting context 中,行內元素從容器的頂端開始,一個接一個地水平排布。水平填充、邊框和邊距對行內元素有效。但垂直的填充、邊框和空白邊不影響其高度。一個水平行中的全部 inline box 組成了名爲 line box 的矩形區域。 line box 的高度始終容下全部的 inline box ,並只與行高有關。 line box 的寬度受到父容器和浮動元素存在的影響(這就是文本環繞浮動元素)。若是 line box 的寬度小於容器, line box 的水平排布就取決於 text-align 。若是 line box 的寬度大於容器,則截斷 line box 並換行在新的 line box 中從新排布元素(截斷處不該用 padding 和 margin 值)。若是 line box 沒法截斷,如單詞過長或者指定不換行,則會溢出容器。blog
浮動的框能夠向左或向右移動,直到它的外邊緣碰到包含框或另外一個浮動框的邊框爲止。圖片
因爲浮動框不在文檔的普通流中,因此文檔的普通流中的塊框表現得就像浮動框不存在同樣。文檔
CSS 浮動get
請看下圖,當把框 1 向右浮動時,它脫離文檔流而且向右移動,直到它的右邊緣碰到包含框的右邊緣:it
再請看下圖,當框 1 向左浮動時,它脫離文檔流而且向左移動,直到它的左邊緣碰到包含框的左邊緣。由於它再也不處於文檔流中,因此它不佔據空間,實際上覆蓋住了框 2,使框 2 從視圖中消失。
若是把全部三個框都向左移動,那麼框 1 向左浮動直到碰到包含框,另外兩個框向左浮動直到碰到前一個浮動框。
以下圖所示,若是包含框太窄,沒法容納水平排列的三個浮動元素,那麼其它浮動塊向下移動,直到有足夠的空間。若是浮動元素的高度不一樣,那麼當它們向下移動時可能被其它浮動元素「卡住」:
浮動框旁邊的行框被縮短,從而給浮動框留出空間,行框圍繞浮動框。
所以,建立浮動框可使文本圍繞圖像:
要想阻止行框圍繞浮動框,須要對該框應用 clear 屬性。clear 屬性的值能夠是 left、right、both 或 none,它表示框的哪些邊不該該挨着浮動框。
爲了實現這種效果,在被清理的元素的上外邊距上添加足夠的空間,使元素的頂邊緣垂直降低到浮動框下面:
這是一個有用的工具,它讓周圍的元素爲浮動元素留出空間。
讓咱們更詳細地看看浮動和清理。假設但願讓一個圖片浮動到文本塊的左邊,而且但願這幅圖片和文本包含在另外一個具備背景顏色和邊框的元素中。您可能編寫下面的代碼:
.news { border: solid 1px black; }
.news img { float: left; }
.news p { float: right; }
<div class="news"> <img src="news-pic.jpg" /> <p>some text</p> </div>
這種狀況下,出現了一個問題。由於浮動元素脫離了文檔流,因此包圍圖片和文本的 div 不佔據空間。
如何讓包圍元素在視覺上包圍浮動元素呢?須要在這個元素中的某個地方應用 clear:
不幸的是出現了一個新的問題,因爲沒有現有的元素能夠應用清理,因此咱們只能添加一個空元素而且清理它。
.news { border: solid 1px black; }
.news img { float: left; }
.news p { float: right; }
.clear { clear: both; }
<div class="news"> <img src="news-pic.jpg" /> <p>some text</p> </div><div class="clear"></div>
這樣能夠實現咱們但願的效果,可是須要添加多餘的代碼。經常有元素能夠應用 clear,可是有時候不得不爲了進行佈局而添加無心義的標記。
不過咱們還有另外一種辦法,那就是對容器 div 進行浮動:
.news { border: solid 1px black; }float: left;
.news img { float: left; }
.news p { float: right; }
<div class="news"> <img src="news-pic.jpg" /> <p>some text</p> </div>
這樣會獲得咱們但願的效果。不幸的是,下一個元素會受到這個浮動元素的影響。爲了解決這個問題,有些人選擇對佈局中的全部東西進行浮動,而後使用適當的有意義的元素(經常是站點的頁腳)對這些浮動進行清理。這有助於減小或消除沒必要要的標記。
事實上,W3School 站點上的全部頁面都採用了這種技術,若是您打開咱們使用 CSS 文件,您會看到咱們對頁腳的 div 進行了清理,而頁腳上面的三個 div 都向左浮動。