お前は table-cell に position: relative できなかった人の数を覚えているのか

Minoru Takai(高井 実)

Contact @debiru

この資料について

発表したイベント
CSSイベント「Back to Basics」 http://peatix.com/event/105960
発表日
2015年8月30日
備考
LTなので短めにつくっています.スライドは reveal.js を利用して独自に機能拡張しています.

table-cell に position: relative を指定しても、子孫の absolute の基点にならないよね?

そういう記事みたことある!

table 関連要素って何があるの(7種類!)

display element 種類 #
table, inline-table table テーブル 1
table-row tr 2
table-row-group
table-header-group
table-footer-group
tbody
thead
tfoot
行グループ 3
table-column col 4
table-column-group colgroup 列グループ 5
table-cell td, th セル 6
table-caption caption キャプション 7

仕様はどうなってるの?

CSS2 (2.1) で見るべき箇所は3箇所

  • 9.3.1 位置決め方式の選択 'position' プロパティ (Ja / En)
  • 9.1.2 包含ブロック (Containing blocks) (Ja / En)
  • 10.1 包含ブロックの定義 (Ja / En)

9.3.1 'position' プロパティの値の効果 (Ja / En)

  • relative が適用された要素は、
    自身の位置のオフセットを相対的に変更できる。
  • ただし、「テーブル」を除く、
    「(6種の)テーブル関連要素」にはこの効果は定義しない

9.1.2 包含ブロック (Containing blocks) (Ja / En)

  • 大抵の要素は、自身のボックスについて、
    包含ブロック基点にして位置が決まる。

10.1 包含ブロックの定義 (Ja / En)

  • 自身の基点となる包含ブロックどれになるかというと…
  • 自身が absolute なら、
    fixed か absolute か relative である最も近い先祖になる。

というわけで仕様によると

relative が適用されると2つの効果が得られる

  • 自身の位置のオフセットを相対的に変更できるようになる
  • absolute である子孫の要素の位置の基点になれる
  • でも6種のテーブル関連要素には効果は未定義である

この未定義ってオフセット効果だけじゃないの?
読み方が悪い?どういうことなの?
で、実際どうなのよ。

実際の挙動をみてみる

  • (1-A) IE で基点
    (1-B) IE でオフセット
  • (2-A) Chrome / Safari / Opera で基点
    (2-B) Chrome / Safari / Opera でオフセット
  • (3-A) Firefox で基点
    (3-B) Firefox でオフセット

(1-A) 基点になれる?(IE 8/9/10/11)

table と table-cell と caption が基点になっている

(row, row-group は無視される)

(1-B) オフセットとれる?(IE 8/9/10/11)

table と table-cell と caption がオフセットできている

(row, row-group は無視される)

(2-A) 基点になれる?(Chrome / Sa / Op)

table と table-cell と caption が基点になっている

(row, row-group は無視される)

(2-B) オフセットとれる?(Chrome / Sa / Op)

table と table-cell と caption がオフセットできている

(row, row-group は無視される)

そして Firefox では

(3-A) 基点になれる?(Firefox)

おい table 仕事しろ

(3-B) オフセットとれる?(Firefox)

table のオフセットは効いている

table-cell に relative 使えない伝説が始まる

ブラウザ 基点 オフセット
IE 8/9/10/11 1, 6, 7 1, 6, 7
Chrome, Safari, Opera 1, 6, 7 1, 6, 7
Firefox 1

1 table / 2 table-row / 3 table-row-group /
4 table-column / 5 table-column-group /
6 table-cell / 7 table-caption

この分かりにくい仕様のせいで、15年近くもの間、人々を苦しめることに

2000年に2つのバグが Mozilla に報告された

  • Bug 35168 - relative positioning of table cells doesn't work
    バグ報告の内容:「table-cell にオフセットが効かない
  • Bug 63895 - relative/absolute positioned table not abs pos containing block
    バグ報告の内容:「table が基点にならない

Bug 35168 のレポートの流れ

  • 「table-cell に relative してもオフセットが効かねえええ」
  • 『9.3.1 節で table-cell は未定義だから仕方ないんじゃね』
  • 「」
  • (そして2012年頃まで放置される)
  • (2012年頃から「これ結局どうなったの」という感じに)

Bug 63895 のレポートの流れ

  • 実はこのレポートはサマリーが何度か変わっている
    「table の基点」から「table 関連要素の基点」になる
  • table への基点問題は Firefox 10 で修正された(2011年10月
  • table 関連要素は『未定義だから』と修正されない
  • 「未定義って言っても対応してもいいよねえ…ねえ?」という意見がでるものの、対応される気配がないまま

この問題に泣いた人々の数

2000年から2014年頃までに Bug 63895 基点問題の重複レポートが山のように報告される

人々の反応 1

2005年のコメントの時点で「なぜこの大昔のバグが未だに直ってないのか理解できない」

人々の反応 2

2004年のレポート「IE と Netscape は Fine なのに Firefox はダメだ」と言われる

人々の反応 3

2012年のコメント「IE7 ですら定義されてるんだぞ」「Firefox を除いては、他のブラウザで全て動くのに」「この状況をあと何年待てばいいんだ」との声

人々の反応 4

2013年の記事。「Firefox で見ると… FML (最悪)だ」「13年前のレポートが未だに修正されていない」

そして2014年

「Firefox はもうこの仕様を見直すことはないんだ」と table-cell + relative 問題を諦めかけた頃

Firefox 30 (2014年6月)で突然の対応 (A)

table-row-group, table-row, table-cell が基点に対応

(table-caption は対応していない)

Firefox 30 (2014年6月)で突然の対応 (B)

しかしオフセットには対応していない

Firefox は更に進化する

Firefox 37 (2015年3月)での実装 (A)

table-caption も基点に対応(全完

Firefox 37 (2015年3月)で実装 (B)

table-row-group, table-row, table-cell がオフセットに対応

ほぼ全完(table-caption は未対応…これって…)

Firefox「伸び代ですね!

table-cell に relative 使える伝説が始まる

ブラウザ 基点 オフセット
IE 8/9/10/11 1, 6, 7 1, 6, 7
Chrome, Safari, Opera 1, 6, 7 1, 6, 7
Firefox 37+ (2015年3月) 1, 2, 3, 6, 7 1, 2, 3, 6

1 table / 2 table-row / 3 table-row-group /
4 table-column / 5 table-column-group /
6 table-cell / 7 table-caption

CSS3 では従来の 9.3.1 節の undefined が消えた

  • relative にすると相対的にオフセットされる。テーブル関連は次の通り。
  • 「行グループ」「行」はオフセットされるセルが rowspan しているときは、行に含まれるセルのみがオフセットされる。
  • 「列グループ」「列」には何の効果もない
  • 「キャプション」「セル」はオフセットされる。セルが rowspan / colspan しているときは、そのセル全体がオフセットされる。

使える伝説に気付き始めた方々

日本語の記事はあまり見つからなかったです

終わり

  • border-collapse: collapse だと IE / Firefox で border が隠れるとかあります
  • collapse アルゴリズムに問題があるので separate を使うことをおすすめします
  • 今回は細かい挙動については話せませんでした。続きは Twitter でどうぞ
  • ブラウザテストに用いたテストケースはこちらです

Mozilla に15年間苦悩した人々のことを思い出しながら table-cell + relative を活用してください

relative のオフセット基点の話でした。