Shiki’s Weblog
ESウェブブラウザ通信 - CSS 2.1 Test Suite #19
2012/03/12 #ESウェブブラウザ通信
前回は インライン要素の背景やボーダーの描画処理を改善しました。今回は、 vertical-alignの処理で未対応の箇所を 実装していきます。 vertical-alignは、インライン要素に指定された場合と、テーブルのセルに指定された場合とで効果が異なります。 CSS 2.1の仕様書では 、それぞれ 10.8.1 と 17.5.3 に記載されています。今回はこの2つのセクションをCSS 2.1のテスト スイートを使ってテストしながら実装を進めていきます。
インライン レベル要素の'vertical-align'
・vertical-align-115 このテストでは'sub'をテストしています。
r2456
r2457でsub, superに対応しました。位置決めに必要な情報はTrueTypeフォントのOS/2テーブルから取り出しています。
r2457
このテストはイメージをbaselineに合わせて表示してみるテストです。成功すれば猫の絵の下に緑色のバーが表示されます。
r2476
このテストでは、なぜバーが表示されるのか不思議だったのですが、試しにイメージの左右にテキストを入れてみると、
試しにイメージの左右にテキストを入れてみる
上図のように猫の下にバーが見えてきます。というわけで、ラインボックス内にテキストが一切ない場合でも、font-sizeプロパティーは有効で、ベースラインの計算にはそのフォントのメトリックも影響する、という解釈のようです。すこし無駄な処理のような気がしなくもありませんが、CSS 2.1のテストスイートの中にはこの動作に依存しているテストがいくつかあるようです。r2477で対応しています。
r2477
このテストでは'middle'をテストしています。
r2477
r2478でmiddleの指定に対応しました。
r2478
このテストでは、テスト本来の問題ではなくて、r2478ではイメージが不正に拡大されて表示されていました。これは、img要素のイメージを簡易的にCSSの背景画像と同じように処理していたためです。そのため、img要素に余白やボーダーがある崩れてしまっていました。
r2478
r2479でAcit2テストの時に用意したobject要素用のコードをベースにimg要素の処理を修正しています。
r2479
・vertical-align-boxes-001 このテストでは、いろいろなvertical-alignの指定をまとめて使っていて、成功すると青いボックスが横一列に並んでひとつのボックスのように見えます。r2480では、未対応のtext-topとtext-bottomを使用している部分がずれていました。
r2480
r2481でひとまずtext-topとtext-bottomに対応させています。なお、 r2481の後、他のテストで見つかった細かい修正がr2484まで続いています:r2482(単純なバグ修正),r2483(ラインギャップの考慮し忘れ),r2484(ディセントの処理のバグ修正)。
r2481
r2484までで、10.8.1に関してはテストスイートのテストにPASSするようになりました。ただtop, bottomの実装がまだ仕様通りでない部分があるので、今後まだ修正が必要になりそうです。今回は続いてテーブル セルのvertical-alignの処理に進みます。
テーブル セルの'vertical-align'
・vertical-align-baseline-009 このテストに関しては、かなり初期に実装したESウェブ ブラウザのHTMLテーブルモデルの実装だと表をレイアウトすることができませんでした。
r2486
r2487では、HTMLテーブル モデルの実装を修正するかわりに、この古いコードは破棄して、html要素で記述されたテーブルも#17でテストしながら実装したCSSテーブル モデルで処理するようにしています。そのため、JavaScriptからテーブルをDOMで操作したりすると、HTMLテーブル モデルと違う表示をする場合が出てくると思いますが、それはそういう事例が実際に問題になったときに対応することしておきます。
r2487
・table-height-algorithm-031その1 このテストは、仕様書17.5.3の、
In CSS 2.1, the height of a cell box is the minimum height required by the content.
という部分のテストにもなっています。
r2487
r2487の段階ではこの仕様に未対応で、左側の列の外側のセルも内側のセルも height: 100pxの設定にそのまましたがって高さが100pxになってしまっています(内部で通常のブロック レベル ボックスと同じレイアウト処理しているため)。r2488で、まずこの点を修正しています。
r2488
このテストでは本来はさらに画面上に見えている2つの"Filler Text"が垂直方向で揃うかどうかが問題なのですが、この点は今回あとで修正します。・table-height-algorithm-002 このテストではtable要素に設定されたheightもやはり高さの最小値として扱っているかどうかテストしています。
r2488
r2489で対応しています。
r2489
このテストでは、table-rowに設定されたheightについても同様に最小値として扱っているかどうかテストしています。
r2489
r2490で対応しています。
r2490
・table-height-algorithm-031その2 ここまででheightプロパティーの処理は直ってきました。r2491では、セルの'vertical-align'にひとまず対応しました。table-height-algorithm-031では、横一列に揃っていなかったテキストが揃うようになりました。
r2491
・table-height-algorithm-019 このテストは、本来はtable-cellのvertical-alignに指定された'sub'などは適用されずに'baseline'として扱う、という部分のテストです。
r2491
r2491ではその部分ではなくて、単純にセルのbaselineの計算にバグがあって横に揃っていませんでした。r2492で修正しています。
r2492
・table-height-algorithm-032 このテストでは、inline-tableのベースラインとセルのベースラインと同じになっているかどうかテストしています。(r2492はWebKitと同じ崩れ方ですね。 )
r2492
r2493で修正しました。
r2493
・table-height-algorithm-010 このテストでは、HTMLのrowspan属性を使っています。本来は黒と青のボックスが同じ高さにならないといけません。
r2494
r2495でrowspanしているセルのbaselineを、他のセルと別に処理するようにして対応しました。
r2495
・table-height-algorithm-012 010と同様なのですが、vertical-alignに'baseline'が指定されています。
r2495
セルのベースラインは1行目のベースラインと同じなので、この場合はrowspanしていないセルと同様にベースラインを処理するようにr2496で修正しました。
r2496
・inline-table-002b このテストでは、未対応のvisibilityプロパティーを使っている部分で失敗していました。
r2496
テーブル関連の要素以外のvisibilityプロパティーの処理は比較的単純なものなので、r2497で対応させました。
r2497
・inline-block-valign-001 このテストでは、インライン ブロックのベースラインの処理が正しいかどうかみています。
r2497
r2498でインライン ブロックのベースラインの計算のバグを修正しました。この段階でCSS 2.1の実装としては問題ないと思うのですが、このテストではさらにレガシーなHTMLの属性を使っているので、一応対応していきます。
r2498
r2499でtable要素のheight属性に対応しました。この属性についてはHTML 5でも記載がないようですが、メジャー ブラウザはすべて対応している属性なので合わせておきます。
r2499
続いて、r2500でHTMLのvalign属性に対応しました。こちらはHTML 5では未定義ではありませんがobsoleteです。これでメジャーなブラウザと同じ表示になるようになりました。
r2500
・inline-block-valign-002 このテストは、インライン ブロック中にラインボックスが複数作られているような場合のテストになっています。
r2500
r2501で残っていたバグを修正しています。
r2501
・inline-table-valign-001 このテストも崩れている原因はインライン テーブルのベースラインの計算のバグでした。
r2501
r2502で、テーブル ボックスに余白などがあった場合にも正しく計算するように修正しました。
r2502
・inline-table-002a このテストは本来はインライン テーブルのベースラインの計算のテストです。
r2502
r2502では、匿名のセルが作られたときに対応するボックスが生成されないバグが残っていました。r2503で修正しています。
r2503
マージンのつぶし、再び
リグレッションが発生していたので修正しておきます。・margin-collapse-145 いままで成功しているように見えていたこのマージンのつぶしのテストなのですが、セルのvertical-alignに対応したことで問題が見つかりました。
r2504
r2504では、マージンのつぶしの処理の問題で、左側のセルの高さが本当の高さよりもクリアランス相当の16px分低く計算されてしまっていました。ボックスの配置自体は合っていたので、vertical-alignが効いていないときは、正しくレイアウトされているように見えていたのです。それが、vertical-alignが効いてくると、セルの垂直位置を揃えようとして高さの足りない左側のセルの上に不要な余白が挿入されて細い マゼンタ 色のバーが見えてしまう結果になってしまっていました。
r2509
r2509でcollapse throughした最後の子ボックスが消費したクリアランス相当の高さを親の下マージンとして保存できるように修正しています。(collapse throughのマージンのつぶしは本当にややこしすぎだな、と。)
Acid2、14行目
Acid2テストも、セルのvertical-alignの処理に関するバグをひとつ見つけました。
r2506
最後の14行目では、セルを一切含まないテーブルが作られているのですが、そのテーブルのベースラインの計算にバグがありました。r2507で修正しています。
r2507
・table-valign-002 このテストではテーブルをフローティング ボックスにしてテストしています。
r2509
r2509では、テーブルにfloatが設定されている場合でもイン フローのボックスのように他のフローティング ボックスの高さを消費してしまっていたバグがあって、すべての要素に対応するボックスが表示できていませんでした。r2510で、まずこの問題を修正しています。
r2510
続いて、テーブル セルをmiddleやbottomでvertical-alignするときに、セルに設定されているheightの値でレイアウトしてしまっていた問題をr2511で修正しています。CSS 2.1の仕様書からは読み取りにくいのですが、セルのvertical-alignに関しては、セルに設定されているheightの値は無関係ということになっています(参考:Issue 26)。
r2511
これで黄色のストライプは横一列に揃いましたが、最後のテーブルの高さが正しくありません。これはbaselineでvertical-alignするときに、やはりセルに設定されているheightの値を見てしまっていたためでした。r2512で修正しています。
r2512
これでやっとこのテストにPASSできました。現状ではGeckoやWebKitがまだr2511と同じ崩れ方をしています(IEとOperaはPASSしています)。Issue 26を見てみると、このあたりは勧告前のCSS 2.1の仕様書の記載があいまいだったことに原因がありそうです。
まとめ
以上でvertical-alignに関しては、インライン要素の場合、テーブル セルの場合、ともにテストにパスするようになりました。CSS 2.1テストスイート全体の成功率は前回から1%上がって約83%となりました。ただCSS 2.1の章別でみると成功率が80%に満たない章がまだ全体の1/3ほど残っています。次回以降は、このあたりを改善してどの機能も平均的により正しい動作になるように開発していきます。