格式化上下文指的是初始化元素定義的環境。包含兩個要點,一個是元素定義的環境,一個是初始化。
在 CSS 中,元素定義的環境有兩種,一種是塊格式化上下文( Block formatting context ),另一種是行内格式化上下文( Inline formatting context )。 這兩種上下文定義了在 CSS 中元素所處的環境,格式化則表明了在這個環境中,元素處于此環境中應當被初始化,即元素在此環境中應當如何布局等。
以上解釋專業點的說法是:在正常流中的框,都屬于一個格式化的上下文中。
這個上下文可能是塊的,也可能是行内的,但不可能同時是行内的又是塊的。塊框1參與塊格式化上下文。行内框1參與行内格式化上下文。
注:
浮動元素、絕對定位元素,'display' 特性為 "inline-block","table-cell", "table-caption" 的元素,以及 'overflow' 不是 "visible" 的元素,會建立新的塊格式化上下文。
浮動元素
絕對定位元素
行内塊元素
單元格
表格标題元素
overflow 非 "visible"的元素
注意,是這些元素建立了塊格式化上下文,它們本身不是塊格式化上下文。
塊格式化上下文是一個比較抽象的概念。可以把它想象成一個大箱子,很多元素裝在裡面,箱子把它們和外面的元素隔開。
塊格式化上下文是個重要的概念,它對寬高的計算,外邊距折疊,定位等都有一定的影響。
在塊格式化上下文中,框會一個接一個地被垂直放置,它們的起點是一個包含塊的頂部。 兩個兄弟框之間的垂直距離取決于 'margin' 特性。在塊格式化上下文中相鄰的塊級元素的垂直外邊距會折疊( collapse )。
在塊格式化上下文中,每一個元素左外邊1與包含塊的左邊相接觸(對于從右到左的格式化,右外邊接觸右邊), 即使存在浮動也是如此(盡管一個元素的内容區域會由于浮動而壓縮),除非這個元素也建立了一個新的塊格式化上下文。
它與普通的塊框類似,不同之處在于:
可以包含浮動元素2
可以阻止外邊距折疊3
可以防止元素被浮動元素覆寫4
在 CSS3 中,對塊格式化上下文這個概念做了改動,将 "Block formatting context" 叫做 "flow root"。
對于觸發方式也做了修改,更加準确:
The value of 'position' is neither "static" nor "relative".
可見,CSS3 草案中的對觸發方式的描述更加準确,'position' 在 "fixed" 的時候也會建立 "flow root"。這并不是CSS2.1的疏忽, 因為 "position:fixed" 本身就是 "position:absolute" 的一個子類。
注意,"display:table" 本身并不産生 "block formatting contexts"。但是,它可以産生匿名框 6, 其中包含 "display:table-cell" 的框會産生塊格式化上下文。 總之,對于 "display:table" 的元素,産生塊格式化上下文的是匿名框而不是 "display:table"7。
The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap any floats in the same block formatting context as the element itself.
相對于塊格式化上下文,在行内格式化上下文中,框( boxes )一個接一個地水準排列,起點是包含塊的頂部。 水準方向上的 margin,border 和 padding 在框之間得到保留。 框在垂直方向上可以以不同的方式對齊:它們的頂部或底部對齊,或根據其中文字的基線對齊。 包含那些框的長方形區域,會形成一行,叫做行框。
示例代碼:
以上代碼中,無換行符及空格,共形成了 7 個行内框。
示意圖:

行框的寬度由它的包含塊1和其中的浮動元素決定。高度的确定由行高度計算規則決定。
通常,行框的左邊接觸到其包含塊1的左邊,右邊接觸到其包含塊1的右邊。然而,浮動元素可能會處于包含塊1邊緣和行框邊緣之間。 總之,盡管在相同的行内格式化上下文中的行框通常擁有相同的寬度(包含塊1的寬度),它們可能會因浮動元素縮短了可用寬度, 而在寬度上發生變化。同一行内格式化上下文中的行框通常高度不一樣(如,一行包含了一個高的圖形,而其它行隻包含文本)。
如果幾個行内框在水準方向無法放入一個行框内,它們可以配置設定在兩個或多個垂直堆疊的行框中。是以,一個段落就是行框在垂直方向上的堆疊。 行框在堆疊時沒有垂直方向上的分割且永不重疊。
如果一個行内框超出包含它的行框的寬度,它會被分割成幾個框,并且這些框會被分布到幾個行框内。如果一個行框不能被分割(例如, 行内框隻包含單個字元,或者語言特殊的斷字規則不允許在行内框裡換行,或者行内框受到帶有 "nowrap" 或 "pre" 值的 'white-space' 特性的影響),這時,行内框會溢出行框。
如果一個行内框被分割,margin、padding 和 border 在所有分割處沒有視覺效果。
行内框還可能由于雙向文本處理(bidirectional text processing)而在同一個行框内被分割為好幾個框。
由于行框寬度限制(100px),第一個 SPAN 元素形成的行内框,被分割成了 3 段。
1). 行内框在行框中垂直方向上的對齊
行框的高度總是足夠容納所包含的所有框。不過,它可能高于它包含的最高的框(例如,框對齊會引起基線對齊)。 當一個框 B 的高度小于包含它的行框的高度時,B 在行框中垂直方向上的對齊決定于 'vertical-align'2 特性。 'vertical-align'2 預設值為基線( 'baseline' )對齊。
EM 所形成的行内框内容的頂端與行中最高元素的頂外邊界對齊。
2). 行内框在行框中水準方向上的對齊
當一行中行内框寬度的總和小于包含它們的行框的寬,它們在水準方向上的對齊,取決于 'text-align' 特性。 如果其值是 'justify',使用者端也可以拉伸行内框(除了 'inline-table' 和 'inline-block' 框)中的空間和文字 。
由圖可見,浮動元素縮短了目前的行框,并且行内框在對齊的時候是根據行框的寬度,居中對齊。
不包含文本,保留白白符,margin/padding/border 非0的行内元素,以及其他正常流中的内容(比如,圖檔,inline blocks 和 inline tables), 并且不是以換行結束的行框,必須被當作零高度行框對待。就外邊距折疊而言,這種行框必須被忽略。
一旦一個框按照正常流或者是浮動得到定位,它還可以相對該位置而偏移。 這就是相對定位。按照這種方式偏移一個框(B1)不會對後續的框(B2)有影響:
B2 在定位時,就好象 B1 沒有發生偏移一樣
B1 偏移後,B2 不會重新定位
相對定位元素處于正常流中,相對于元素在正常流中的原位置進行定位,偏移後,在正常流中依然占據原有位置。
這也意味着相對定位可能産生框的重疊1。
如果相對定位引起 "overflow:auto" 或 "overflow:scroll" 框的溢出,浏覽器必須允許使用者通路内容,既,建立需要的滾動條,這可能會影響布局。
其中,紅色塊 A 定位的時候,溢出藍色框的顯示範圍。根據标準,應該出現滾動條,以保證使用者可以正常的通路 A 中的内容。
對相對定位溢出的處理,存在相容性問題。請讀者自行測試。
相對定位元素的尺寸,會保持它在正常流中的尺寸。包括換行以及原來為它保留的位置。
對于一個相對定位的元素,'left' 和 'right' 會水準的位移框而不會改變它的大小。'left' 會将框向右移動,'right' 會将框向左移動。 由于 'left' 或者 'right' 不會造成框被拆分或者拉伸,是以,計算後的值( computed value )總是:left = -right。
1). 'left' 和 'right' 的設定值都是 "auto"
如果 'left' 和 'right' 的值都是 "auto" (它們的初始值),計算後的值( computed value )為 0(例如,框區留在其原來的位置)。
2). 'left' 或 'right' 其一的設定值為 "auto"
如果 left 為 ‘auto’,計算後的值(computed value)為 right 的負值(例如,框區根據 right 值向左移)。 如果 right 被指定為 ‘auto’,其計算後的值(computed value)為 left 值的負值。
上述代碼中,DIV 元素是相對定位的元素,它的 'left' 值是 "100px", 'right' 沒有設定,預設為 "auto",那麼,'right' 特性計算後的值應該是 -left,即 "right:-100px"。
3). 'left' 和 'right' 設定值都不是 "auto"
如果 'left' 和 'right' 都不是 "auto",那麼定位就顯得很牽強,其中一個不得不被舍棄。如果包含塊的 'direction' 屬性是 "ltr", 那麼 'left' 将獲勝,'right' 值變成 -left。如果包含塊的 'direction' 屬性是 ‘rtl’,那麼 'right' 獲勝,'left' 值将被忽略。
最後,'left' 應該比較強悍才對。
'top' 和 'bottom' 特性将相對定位元素向上或者向下移動,而不改變其大小。'top' 把框向下移動,而 'bottom' 将其向上移動。 由于 'top' 和 'bottom' 沒有造成框被拆分或者拉伸,計算值總是 top=-bottom,如果兩個都是 "auto",其計算值就都是 0,如果其中之一是 auto,它就是另一個的負值。 如果都不是 "auto",'bottom' 被忽略,這時,'bottom' 的計算值會是 'top' 值的負值。
本文轉自葉小钗部落格園部落格,原文連結:http://www.cnblogs.com/yexiaochai/articles/3678461.html,如需轉載請自行聯系原作者