(理論)'overflow' 屬性究竟適不適用於 'table' 元素?(原: [CSS] 表格上用圓角)

(11/12/01 18:35), Yao Wei (魏銘廷) wrote:
> 2. `display: overflow;` 不能用在 table 上面(規範定義是用在 block
> container),間接影響我要做表格圓角框(我打算對 thead 裡面的元素上背
> 景色,但是背景色跑到角落去了)

做一點跟上面這個問題相關的 CSS 2.1 規範文字探討。這跟 'overflow' 究竟該
不該適用於 'table' 無關(目前沒聽過有人反對 'overflow' 應該可以用在
'table' 上,另外各個瀏覽器實作也大致可用),不過我想點出 CSS 2.1 作為一
份規範的幾個潛在問題,並提出勘誤表上應該怎麼讓 'overflow' 適用於
'table'。探討過程用了很多 RainZhai 的 CSS 2.1 第九章的翻譯,有些我用誇號
再翻一次,希望之後能仔細檢討一次各個段落。

在這裡我先說我的結論:按照當前(錯誤)的 CSS 2.1,'overflow' 的確不能用
在 'table' 上。


== 探討開始 ==

'overflow' 屬性在 CSS 2.1 的相關描述[1]是:

  # 適用於:  塊容器

和

  # 當塊容器元素的內容溢出元素的盒的時候,這個屬性可以用來指定使用者代理
  # 會不會剪裁該內容。

所以這裡的問題變成了「'display:table' 的元素是不是一個塊容器?」這個問
題。在這裡,David Baron 的解釋是:

[[
引用塊容器盒的定義[2]

  # 除了table盒,和可替换元素,一个块级盒同时也是一个块容器盒,一个块容器
  # 盒只包含块级盒子或是建立一个行内格式化上下文来包含行内级盒.不是所有
  # 的块容器盒都是块级盒,不可替换行内块和不可替换table cells是块容器但不
  # 是块级盒
  #
  # (除了表格盒(在後面章節描述)和置換元素之外,一個塊級盒同時也是一個
  #  塊容器盒。一個塊容器盒要不就只包含塊級盒要不就因為建立了行內格式化
  #  上下文而只包含行內級盒。並不是所有的塊容器盒都是塊級盒,非置換行內
  #  塊和非置換表格單元就是塊容器而不是塊級盒。)

所以表格不是塊容器,所以 'display:table' 的元素不是塊容器,所以
'overflow' 不適用。
]]

看起雖然好像就是這樣了,但是問題並沒那麼簡單。表格章節描述 'display:
table' 模型的地方[3]是這樣說的:

  # 表格在這兩種情況都會產生一個稱為表格包裹盒的主塊盒,表格包裹盒裡包有
  # 表格盒與所有表格說明盒(以文件順序)。表格盒是包有內部表格盒的塊級
  # 盒。
  # ...
  # 若表格為塊級,則表格包裹盒是一個 'block' 盒,若表格為行級,則表格包
  # 裹盒是一個 'inline-block' 盒。

也就是 'table' 元素會產生兩個盒:「表格盒」和「表格包裹盒」,儘管表格盒
不是塊容器盒,但是表格包裹盒是塊容器盒(因為根本就是一個 'block')。因
此,上面「所以表格不是塊容器,所以 'display:table' 的元素不是塊容器,所
以 'overflow' 不適用。」的邏輯就不是很順暢,因為 'table' 元素產生兩個
盒,一個是塊容器盒,一個不是,而「'display:table' 的元素是不是一個塊容
器?」這個問題就變成相當模糊了。

儘管如此,要回答「'overflow' 屬性究竟適不適用於 'table' 元素?」這個問
題,其實可以避開這個模糊的問題。同樣的小節還有這樣一段話:

  # 使用者代理會把表格元素上 'position'、'float'、'margin-*'、'top'、
  # 'right'、'bottom'、'left' 屬性的計算值用在表格包裹盒而不是表格盒上
  # ― 其他不繼承的屬性用在表格盒而不是表格包裹盒上。(表格盒與表格包裹
  # 盒沒從表格元素得到屬性值的屬性改使用初始值。)

因為前面那句話沒有提到 'overflow',所以 'table' 元素上的 'overflow' 傳到
表格盒,但是因為表格盒是不是塊容器盒,所以根據 'overflow' 小節的敘述
'overflow' 在 'table' 元素上沒有效果。

[1] http://www.w3.org/html/ig/zh/wiki/CSS2#overflow
[2] http://www.w3.org/html/ig/zh/wiki/CSS2#block-level
[3] http://www.w3.org/html/ig/zh/wiki/CSS2#model

== 規範更改 ==

這裡 CSS 2.1 的邊界折疊王 Anton Prowse 提議[4]把 'overflow' 的敘述改成

  | 適用於:  塊容器與表格盒

這雖然確保了 'table' 元素上可以用 'overflow' 這個原來的問題。但是留下了
兩個問題:

1) 究竟 'display:table' 的元素是不是一個塊容器?

2) 屬性的「適用於」欄位一般都是「元素」的一個分類,像是定位元素、塊級元
素,這裡加了「表格盒」是不是違背了一致性?


這裡一個根本的問題就是 CSS 2.1 裡面「盒」跟「元素」常常混著用,而這裡最
大的問題是「雖然有塊容器盒的定義,但是**沒有塊容器元素的定義**,但是規範
卻一再提到塊容器元素這個詞彙,或是有時候用塊容器稱呼不知道是盒還是元
素。」另一方面,「塊級元素」和「塊級盒」卻是都有定義:

  # 塊級元素是原始文件裡布局成塊(例:段落)的元素。以下的 'display' 讓
  # 一個元素成為塊級:'block'、'list-item'、'table'。
  #
  # 块级盒是参与一个块格式化上下文的盒子.每个块级元素生成一个主要的块级
  # 盒子,其包含子盒子和生成的内容,同时盒子也涉及到定位的方案.
  #
  # (塊級盒是一個參與塊格式劃上下文的盒子。每個塊級元素產生一個包含子
  #  盒與生成內容的主要塊級盒,主要塊級盒也是參與定位方案的盒。有些塊級
  #  元素可能產生主要盒以外的盒:例如 'list-item' 元素,這些額外的盒的定
  #  位相對於主要盒。)


考慮到把 'table'/'inline-table' 加進「塊容器元素」可能會改變 CSS 2.1 現
在行為的兩個地方:

1) '::first-line'/'::first-letter' 適用於「塊容器元素」— 測了一下,沒看
到哪個瀏覽器的 ::first-line/::first-letter 適用在 'table' 裡的
'table-caption'

2) 'unicode-bidi: bidi-override' 適用於「塊容器元素」— 測了一下,只有
WebKit 在 'table' 上的 'unicode-bidi: bidi-override' 會影響裡面的
'table-caption'

再加上以「塊容器元素就是產生的非無名盒都是塊容器盒的元素」定義塊容器盒元
素的話會排除應該是塊容器元素的 'list-item'(標記盒至少在
'list-style-position: inside' 的時候是行內盒)。所以,只好用條列的方式定義:

  | 塊容器元素就是 'display' 是 'block'、'list-item'、'inline-block'、
  | 'table-cell' 的元素。

特別排除 'table' 和 'inline-table'。而 'overflow' 的敘述應該改成


  | 適用於:  塊容器元素、'table' 與 'inline-table' 元素

和

  | 當塊容器盒或表格盒的內容溢出元素的盒的時候,這個屬性可以用來指定使用
  | 者代理會不會剪裁該內容。


(沒有人有什麼異議的話,中文翻譯版我打算就照這樣改並且留一個到這封信的註
解圖示)

[4] https://www.w3.org/Bugs/Public/show_bug.cgi?id=15381

== 結論 ==

1) CSS 2.1 就是充滿未定義或是定義不清詞彙的一份規範。引入「塊級盒」和
「塊容器盒」這兩個詞彙僅僅是 2010 年 8 月的事(CSS 2.1 Issue 120[5]),
在這之前規範似乎到處都很含糊的用「塊盒」這個字眼。

2) 要多注意 'table'/'inline-table' 會產生表格盒和表格包裹兩個盒這點,下
一封信討論三個相關的實際問題。

[5] http://wiki.csswg.org/spec/css2.1#issue-120



此致

呂 康豪(Kenny), 中文興趣小組W3C連絡人
新浪微博: http://t.sina.com.cn/1950042164
Google+: https://plus.google.com/112088462407783855918/posts

Received on Thursday, 22 March 2012 11:03:12 UTC