ヘッダ固定テーブルをCSSで実装してはいけない
はじめに
企業向けシステムでは、ヘッダ固定テーブルの実装を要求されることがある。ヘッダ固定テーブルとは、
- テーブル(<table>タグ)である
- テーブルの横に、テーブル部分のみのスクロールバーが表示される
- テーブル部分のみのスクロールバーでスクロールしても、テーブルのヘッダ行はスクロールしない
といった特徴を持つもので、いわばExcelの[ウィンドウ枠の固定]機能のWebアプリ版だ。
CSSで実装するには
Pushpin Headerと呼ばれるテクニックがある。positionプロパティを巧みに使った華麗なテクニックだ。ちなみに私は、このテクニックを初めて見たときは理解できなかった。positionプロパティについての正確な知識がないと、理解は難しい。
Pushpin Headerテクニックの問題点
上記リンク先のページをSafari*1で表示すると、ヘッダとボディの間にスペースが空いてしまう。この問題については、テクニックの解説でも記述されている。
CSSハックの問題点
それは、CSSハックの持つ性格によると思う。CSSハックはブラウザのバグを利用したテクニックである。バグなのだから、いつ修正されるかわからない。インターネットでCSSハックを紹介しているページの作成者は、ページ作成時には実際にブラウザで表示して動作を確認しているだろう。それが、時間の経過とともにブラウザのバージョンが上がり*2、CSSハックが期待通りに動作しなくなるのだ。
CSSでの実装に対する結論
- ヘッダ固定テーブルをPushpin Headerテクニックで実装
- 対応ブラウザにSafariが含まれている
を同時に満たそうとすると、CSSハックの使用を余儀なくされる。しかし、CSSハックの性格は上記のとおりなので、時間の経過とともにシステム修正を迫られる可能性が高まっていく。企業向けシステムでは、いったんリリースしたものはできるだけ修正したくない。
システムの対応ブラウザのバージョンを、「IE 6.0以上」などではなく「IE 6.0.xxxx.xxxx.〜限定」などとできればよいのだが、そんな過保護な動作環境定義はまずない。
よって、システムの対応ブラウザを限定できない場合は、CSSでの実装は諦めた方が良い。
でも実装しなければならない…
CSSでの実装を諦めた場合、どうやって実装すればよいのか。簡単だ。ヘッダとボディを別テーブルとすれば良い。Web標準に反することは間違いない*3。しかし、納期のある仕事としてシステム開発をしているのだから、割り切りも必要だと私は思う。
テーブル分割での実装サンプル
以下のようなコードとなる。
<table style="width: 150px;"> <tr> <th style="width: 50px;">ほげ</th> <th style="width: 100px;">ふが</th> </tr> </table> <div style="height: 100px; overflow: auto; width: 167px;"> <table style="width: 150px;"> <tr> <td style="width: 50px;">ほげ1</td> <td style="width: 100px;">ふが1</td> </tr> <tr> <td style="width: 50px;">ほげ2</td> <td style="width: 100px;">ふが2</td> </tr> <tr> <td style="width: 50px;">ほげ3</td> <td style="width: 100px;">ふが3</td> </tr> <tr> <td style="width: 50px;">ほげ4</td> <td style="width: 100px;">ふが4</td> </tr> <tr> <td style="width: 50px;">ほげ5</td> <td style="width: 100px;">ふが5</td> </tr> </table> </div>
このコードサンプルはあくまでイメージであり、実際には
- classでスタイル指定する
- 2つのテーブル全体を囲む要素との位置関係を適切に指定する
などとしなければならない。
このコードサンプルのポイントは
- テーブルセルのwidthを明示的に指定している
- ボディ部のテーブルを囲むdivに対し、heightを指定してoverflow: autoを指定している
といった点だ。