CSSだけでテーブルの縦横2列を固定してスクロールできるようにする
※この記事ははてなブログ、別アカウント(hyiromori)から引っ越しました
はじめに
タイトルのような、とても大変な要件のテーブルを作って欲しいという要望があったので、その際に試行錯誤した結果を記録しておいたエントリです。
サンプル
コードの解説
このコードではposition: sticky
を使用することで、テーブルの行、列を固定しています。
position: sticky
は top
right
bottom
left
と組み合わせて使うことで
position: relative
と position: absolute
を組み合わせたような動きが可能になる指定です。
Safari ではposition: -webkit-sticky;
のようにベンダープレフィックスをつけないと動作しませんでした。
詳細はMDNの解説をご覧ください。
position: sticky
の対応状況
Can I Useによれば、モダンブラウザは対応済みです。
ちなみにChromeなどは
Supported on th elements, but not thead or tr
とある通りthead
tr
にバグがあるようです。
このサンプルはthead
tr
に指定していないので、対応ブラウザなら正常に動作するはずです。
幅と高さの制約
position: sticky
を使用するため、一部のセルは幅または高さを固定する必要があります。
今回のサンプルは、縦横それぞれ2列を固定するため、以下を固定しなければなりません。
- 1行目の高さ(2行目の
top
を指定しないと固定できないため) - 1列目の幅(2列目の
left
を指定しないと固定できないため)
実際に使用する場合は、これらのセルを指定した幅と高さで必ず収まるように要素を配置しないといけません。
表示上の制約
テーブルの親要素の幅が十分に広い場合、右側に余白ができてしまう場合があります。
これは table {width: 100%}
を指定しても解消できませんでした。
WindowのResizeイベント や
MutationObserver を使って、
ある程度の幅以下になったら横スクロールを適用するという方法で乗り切りました。
ResizeObserverも使えますが、まだまだ対応ブラウザが少ないです。
対応ブラウザが増えたらこちらも使えるかもしれません。
Discussion