2005-08-28

Simplier Block.

上次我們在 Simple Block, Simple Inline 裡面從 HTMLCSS 兩方面稍為了解了 block 和 inline 和它們之間的分別,今次我們將會更全面地看看 CSS 中所謂的 block boxes 。

對於 display property ,下面的 value 會令一個 element 變成 block-level (從這裡開始我們會稱這些 elements 為 block-level elements) 。

  • block
  • list-item
  • run-in (某些情況)
  • table (有點不同)

另外還有 floatsabsolute positioning 的場合會產生 block boxes ,這不在本文的討論範圍內。

Principal Block Boxes

Block-level elements (table 除外) 會產生所謂的 principal block boxes ,這 principal block boxes 中只能容納 block boxes 或是 inline boxes ,不能兩樣都有。

Anonymous Block Boxes

那麼,如果像下面遇到同時含有 block content 和 inline content 的場合要怎麼辦呢?

<div>
 Some Text
 <p>More Text</p>
 Much More Text
</div>

如此這般 CSS 會假定 "Some Text" 和 "Much More Text" 也被一個 block boxes 包圍著,而這些虛構的 boxes 便是所謂的 anonymous block boxes ,請看下圖。

Figure showing how anonymous block boxes are formed.

就是說 div principal block box 裡面有三個 block boxes 。

  • 包圍著 "Some Text" 的 anonymous block box 。
  • p block box 。
  • 包圍著 "Much More Text" 的 anonymous block box 。

List-Item Boxes

一個擁有 display: list-item 的 element 也會像其他 block-level elements 一樣產生一個 principal block box ,除此以外還會附加一個 marker box 用來表示自己是 list item (在 list-style-type property 的 value 非 none 的場合) 。 Marker box 出現的位置是由 list-style-position 這個 property 來決定的,如果 value 為 outside 的話, marker box 就會放在 principal block box 的外面;反之如果為 inside 的話, marker box 將會成為 principal block box 內的第一個 inline box 。關於具體 marker box 的 positioning , specs 本身沒有說明過,所以各家各派對於 marker box 的處理方式都不同。

Principal block box 的一系列 background properties 將不會應用在 marker box 上,另 list-style-position 的 value 為 outside 的話, marker box 的背景將會是透明。

Table Boxes

display property 為 table 的 element 和其他 block-level elements 不同,它並不會產生 principal block box ,取而代之的是產生一個 anonymous block box 來包含著 table box 本身和 caption box (which will generated by caption element) 。下面所有在 table box 上的 properties 都會被應用到 anonymous block box 上。

  • position
  • float
  • margin-top, margin-right, margin-bottom, margin-left
  • top, right, bottom, left

而 table box 則會使用這些 properties 的 initial value 。

Run-in Boxes

不在本文的討論範圍內。

Block Formatting Context

這是指在一個 document 中, block boxes 到底會以怎樣的方式來排列,換一個方式說就是「 (Visual) Browsers 放置 block boxes 的規則」。

簡單說,就是 block boxes 從上到下一個個的排列。

複雜說,我也不知道要怎麼說 XD 。

用上面在 Anonymous Block Boxes 裡提過的的例子。排列首先是第一個 anonymous block box ,接著是 p block box ,最後是第二個 anonymous block box ,三個 block boxes 的左邊界都會緊貼著 div block box 的左邊界 (以從左到右的書寫習慣來說) 。

Floats 和 absolutely positioned elements 、 inline-blocks、 table-cells 和 overflow value 不是 visible 的 elements 都會創立新的 block formatting contexts 。

Collapsing Margins

Block boxes 之間的垂直距離是由 margin properties 當中的 margin-topmargin-bottom 來決定的,而當兩個相鄰的 block boxes 的 margins 接觸,它們的 margins 就會塌陷 (collapse) ,舉例。

<div style="margin-bottom: 20px;"></div>
<p style="margin-top: 10px;"></p>

這樣 div block box 和 p block box 的距離會是 20px ,而不是 20px + 10px = 30px 。

Figure showing the collapsing margins of two siblings block box.

Block box 本身跟它 parent 的垂直 margins 也有可能會 collapse ,條件是中間沒有 padding 或是 border 阻隔住,像這樣。

<div style="margin-top: 10px;">
 <p style="margin-top: 20px;"></p>
</div>

Figure showing the collapsing margins between parent and it's child.

總而言之,當兩個 block box 的 margin 直接接觸,就會出現 collapse 。

Block Box Dimensions

Block boxes 的大小被四個要素影響著。

  • Content Area (width & height)
  • Padding Area (padding-*)
  • Border Area (border-*)
  • Margin Area (margin-*)

這四個 areas 的周界稱為 edge ,當中 content/margin edges 又稱 inner/outer edges ,除了 content area 外其他 area 都不是必要的 (也就是說它們可以被零化掉 XD) 。要用文字說明他們之間的關係會有點累贅,請看下圖。

Figure showing the relation of four areas above.

Padding area 跟 border area 是被加在 content area 上面的,而 margin area 而是被放在 block box 外面的空間,所以 margin area 不會承受到 block box 本身的 background properties ,背景永遠都是透明的。

IE Old Block Box Model

這是舊版本的 Internet Explorer 對於 block boxes 錯誤的拴譯,現在有很多人還是以為這是正確的方法。

舊版 IE 把 widthheight properties 的 values 當成是整個 block box 的大小,也就是 content area + padding area + border area 的總和,而不是只有 content area 。

這樣 standard-compliant 的 browsers 在 render 一些比較老舊的網頁時就會造成麻煩。 Opera 跟 新版 IE 都是透過檢查網頁的 DTD 宣告進入 quicks mode 來進行支援。


下一篇將會集中了解 inline boxes 。