float,position,relative,absolute,文檔流這些關鍵術語解惑

在CSS編程中,相信很多人對於上面標題中的這些術語有很大的疑惑,接下來讓我們一點點撥開它們的神祕面紗,以及糾正幾個關鍵性的錯誤,通篇文章我就不提供圖示了,我想能看到我這篇文章的人估計也對這些術語表現出來的圖示已經很清楚了,這裏就不再麻煩上圖了。
在解釋之前,首先說幾本CSS的經典之作(要搞前臺的人應該必讀的):

    1,Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification  這是最最權威的手冊,是標準規範,可惜是英文的,實際上那些翻譯人士完全可以出版一本這樣的中文版。

    2,CSS: The Definitive Guide, 3rd Edition,這是O'Reilly出的書,有中文版《CSS權威指南》,這本書不錯的。

    好了,我們開始進入我們的話題:

    首先,我們來一段英語和語文知識,"The stream flow to the sea",翻譯成中文:“溪流流向大海”。嗯,英文很好理解,stream:溪流,flow:流向。但是中文呢?“溪流”可以縮減成一個“流”字,那麼這句話就成了“流流向大海”,暈了,2個流,連起來讀讀看“流流”。嗯,我說到這裏,估計有些相當聰明的人馬上醒悟到了,馬上醒悟到困惑他多年的疑問解決了。嗯,困惑大家的原來是中文和英文的翻譯歧義造成的,“流流”,第一個“流”是名詞,翻譯自stream,表示實實在在的內容,類似文件流(編程的人最熟悉這個了,文件操作麼太重要了,什麼InputStream,OutputStream)。第二個“流”是動詞,翻譯自flow,表示“流向”。

    搞明白了“流”的關鍵以後,接着讓我們再繼續挖掘下去:

    the normal flow of the document,讓我們好好翻譯這句話:文檔的正常流向。嗯,這個時候最最關鍵的問題來了,咱們中國人一向惜字如金,曾經在很小的時候,就給我們灌輸中文的奧妙之處,比如”僧敲月門下“,到底是敲好呢,還是推的好,字字斟酌過去。於是翻譯上面一句話的時候,有些聰明人士就開始玩起中文的奧妙來了,翻譯成了”文檔的正常流“,嗯,這個還算是好的,更絕的是翻譯成了”文檔流“。嗯,我寫到這裏,相信所有的大家都應該明白了,問題原來出在這裏。你翻譯成了”文檔流“了,誤導了大家,因爲”文檔流“是名詞,根據詞面上的意思以及程序員的編程經歷,理所應當的認爲是文檔的流內容了,倒翻過去,應該是document stream,一個英文單詞的差別,意義可是千差萬別了。至於翻譯成”文檔的正常流“也存在同樣的問題,儘管比”文檔流“稍微好點。

   好了,搞明白了上面的翻譯問題,讓我們回到CSS Specification中,看看它是如何解釋”文檔的正常流向“(千萬不要縮減成”文檔流“哦,以後永遠記住了)。

   在http://www.w3.org/TR/CSS21/visuren.html#positioning-scheme中說道:

In CSS 2.1, a box may be laid out according to three positioning schemes:

Normal flow. In CSS 2.1, normal flow includes block formatting of block-level boxes, inline formatting of inline-level boxes, and relative positioning of block-level and inline-level boxes.
Floats. In the float model, a box is first laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float.
Absolute positioning. In the absolute positioning model, a box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block.
讓我這裏稍微解釋一下:(有些翻譯上的細節我就不考慮了,大致意思不會出錯即可)

   一個box的佈局滿足3種定位模式:

   1,正常流向:塊級、行內、以及相對定位的那些元素。

   2,浮動:首先根據正常流向佈局,然後脫離正常流向(意思是:不再是正常流向了)浮動到左邊或者右邊,box內的剩餘內容沿着這個浮動元素的周圍佈局。

   3,絕對定位:box從正常流向中完全移除(意思是:和上面的float相比,就根本沒有正常流向過)。

   嗯,看到這裏,大家就開始搖頭了,這還是沒有說明白啊,而且越說我越糊塗了。嗯,我知道你在想什麼,呵呵。

   上面這一段是爲了解釋”脫離(移除)文檔正常流向“這個概念的,而不是解釋”浮動、定位“這些具體含義的。再強調一下:”脫離(移除)文檔正常流向“是指:不再是文檔的正常流向了。和文檔的流內容、空間沒有任何關係。或者更直白一點說:不再是是文檔的正常佈局了,而是發生變化的佈局。

    舉個例子說一下:一個div,沒有任何樣式的時候,屬於”塊級元素“,那麼應該符合上面3種定位模式中的”正常流向“模式,假如給這個div加上float:left屬性,那麼 the div has been taken out of the normal flow of the document,也就是不再是正常流向了,那麼屬於什麼啊?恩,只有3種模式,不屬於正常流向,應該屬於”浮動“這個模式。那麼對於瀏覽器引擎來說,就採用”浮動“這種模式的渲染引擎來處理該div。

在css中有一個z-index屬性,因爲網頁是“立體的”,它有z軸,這個z軸的大小就由z-index控制。默認情況下,所有頁面元素均位於z-index:0這一層,而這一層順序排列的元素就構成了“文檔流”。無論是position還是float,它們都是通過改變文檔流來實現定位。

css有三種基本的定位機制:文檔流、浮動和絕對定位。除非專門指定,否則所有元素都在文檔流中定位。也就是說,文檔流中的元素的位置由元素在 X(HTML) 中的位置決定。css定位的基本思想很簡單,它允許你使得元素相對於其正常應該出現的位置,或者相對於父元素、另一個元素甚至瀏覽器窗口本身的位置來進行定位。

CSS定位大致可以分成三類模型:普通流模型、浮動模型、和定位模型;

普通文檔流:顧名思義,普通流中的元素的位置由在HTML中的位置決定,根據上下級和前後的順序,一個一個的排列在界面上;當然根據元素的類型不一樣,排列的方式會不一樣,但先後順序,顯示層次關係不會改變;

    一般在HTML元素分爲兩種:塊級元素和行內元素。像div,p這些的元素屬於塊級元素;而span,strong等屬於行內元素。塊級元素是從上到下一行一行的排列,默認一個塊級元素會佔用一行,而跟在後面的元素會令起一行排列;行內元素是在一行中水平佈置,從前到後的排列;如下面的css代碼:
我是塊級元素,我單獨佔一行
我是塊級元素,我一行一行的排列
我的行內元素,我水平的排列 我是行內元素,沒有那麼霸道

CSS普通文檔流

(一)float:

float屬性定位的元素位於z-index:0層。它是通過float:left和float:right來控制元素在0層左浮或右浮。float會改變正常的文檔流排列,影響到周圍元素。float元素在文檔流中一個挨一個排列。但注意,只是float元素之間一個挨一個排列,對於非float的元素,float元素是視而不見的,會越過它們。

如下面的一段代碼:

<html>
<head>
<styletype="text/css">
    .fl{float:left;background:red;border:solid 1px #00f;}
    .nfl{background:#ff0;border:solid 1px #000;}
</style>
</head>
<body>
    <spanclass="fl">我是float元素1</span>
    <spanclass="nfl">我是非float元素</span>
    <spanclass="fl">我是float元素2</span>
    <spanclass="fl">我是float元素3</span>
</body>
</html>

1、2、3三個元素是float的,它們會越過非float元素一個挨一個排列,把非float元素擠到最後了。效果如下圖:

概括來說,float:left時,會把非float元素擠到所有float元素的右邊,float:right時是擠到左邊。

(二)position:

position屬性包括下面四個值:

static(默認)
元素框正常生成。塊級元素生成一個矩形框,作爲文檔流的一部分,行內元素則會創建一個或多個行框,置於其父元素中。
relative
元素框偏移某個距離。元素仍保持其未定位前的框的形狀,它原本所佔的空間仍保留。
absolute
元素框從文檔流完全刪除,並相對於其包含塊定位。包含塊可能是文檔中的另一個元素或者是初始包含塊。元素原先在正常文檔流中所佔的空間會關閉,就好像元素原來不存在一樣。元素定位後生成一個塊級框,而不論原來它在正常流中生成何種類型的框。
fixed
元素框的表現類似於將 position 設置爲 absolute,不過其包含塊是視窗本身。
設置absolute或relative會讓z-index的值大於0。不同的是,absolute完全脫離文檔流,不再在z-index中保留佔位符,而relative雖然自己已浮起來,但仍然會保留自己在z-index:0中的位置,因此relative在z-index:0層中的相鄰元素不會因此受到影響。下面是具體用法。

  1. 靜態(static):

元素順序顯示,在一個文檔流中,一個挨着一個,但是不像relative那樣可以設置top之類的。靜態定位僅僅意味着內容遵循正常從上到下的HTML流。

  1. 相對(relative):

一個相對定位的元素相對它在HTML流中的當前位置而放置。移動一個帶有相對定位的元素,在該元素本該放置的地方留下了一個“洞”。相對定位的主要用處不是移動一個元素,而是給行內在它內部的絕對定位的元素設定一個新的參考點。

position: relative的元素相對於自己本來應該在的位置進行偏移,偏移後的位置可能覆蓋別人(是漂浮在上方)。它原來的位置也空着,因爲它會被加入到文檔流中。

  1. 絕對(absolute):

絕對定位讓你通過以pixel、em、percentage來指定一個左、右、上或者下的位置來確定一個元素的位置。此外,絕對定位的元素被完全與頁面流分離,換句話說,網頁上的其他東西甚至不知道這個絕對定位的元素的存在。

absolute定位的一般用法:

如果一個標籤有一個絕對的位置,並且它不在任何其他應用了absolute、relative或者fixed定位的標籤裏面,那麼它是相對於頁面(body元素)進行定位的。
如果一個標籤處在另一個帶有absolute、relative或者fixed定位的標籤裏面,那麼它是相對於該元素的邊界進行定位的。
即,position: absolute的元素在static的父元素中是相對頁面(不是瀏覽器窗口)進行偏移,在非static父元素中(通常是relative,因爲如果父元素是absolute,那父元素還要向上找非static祖先元素)是相對父元素進行偏移。
4. 固定(fixed):

一個固定的元素被鎖定在屏幕的位置上。fixed是相對瀏覽器窗口的固定位置定位,如網頁中的“回到頂部”按鈕。

注意:不要試圖給同一個樣式既應用float屬性又應用任何一種定位,除了靜態或者相對定位之外。浮動和絕對或者固定定位不可能同時作用在同一個元素上。

參考資料:

  1. w3c school

  2. 《CSS實戰手冊》

  3. 《編寫高質量代碼——Web前端開發修煉之道》

from: http://my.oschina.net/warmcafe/blog/83768

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章