【小ネタ】CSS だけで Table 要素をレスポンシブ対応させる方法

モバイルファースト、レスポンシブデザイン1)ここで言うレスポンシブデザインとは、ワンソースで複数スクリーンサイズに対応するテクニックのことを指します。というキーワードがWeb業界に定着して久しいですが、当ブログも御多分にもれずモバイルファースト & レスポンシブデザインの設計に則って作られています。一般的にレスポンシブデザインは、コンテンツ表示領域や表示される端末に応じてレイアウトやコンテンツ自体の種類や数をフレキシブルに制御するテクニックのことです。そんな中、Table というコンテンツは名前の通り『表』というレイアウト自体に大きな意味を持つため、中々フレキシブルにレイアウトを変えるのが難しかったりします。レイアウトを変えることでコンテンツの持つ意味が失われてしまっては元も子もないですからね。

そんな厄介な Table 要素をレスポンシブデザインに対応させる小ネタを紹介したいと思います。

事前知識 - Table 要素の display 属性

CSS には display 属性という要素の表示形式を指定する仕様があります。inline は文章の一部として使用される要素で前後が改行されず、block は一つのまとまった単位として表示されるもので前後が改行されるというものですね。none は画面から要素が完全に消え、他の要素に影響を与えません。この辺は CSS を普通に書いていれば必ずと言ってよいほど使われるものです。

で、table 要素ですが、CSS を使わずとも最初から table レイアウトという表示が実現されています。つまり table の各要素には inline でも block でもない display 属性が指定されているというわけです

table 要素に関する dispaly 属性
説明
table table要素のような表示となる
inline-table インラインレベルのテーブルとなる
table-row-group tbody要素のような表示となる
table-header-group thead要素のような表示となる
table-footer-group tfoot要素のような表示となる
table-row tr要素のような表示となる
table-column-group colgroup要素のような表示となる
table-column col要素のような表示となる
table-cell td要素のような表示となる
table-caption caption要素のような表示となる

このように table は関連する各要素に対して固有の display 属性がデフォルトで設定されています。決して table という HTML タグ自体がテーブルレイアウトを実現しているのではありません。ならばこの dispaly 属性を CSS 側でどうにか制御すれば、モバイル端末といった表示領域が狭い環境にも適したレイアウトが組めるということになります

DEMO

See the Pen Blocked table - Demo of Responsive table by wakamsha (@wakamsha) on CodePen.

こちらのデモをベースにしていきます。

とりあえず全部ブロック要素にしとけ

何も考えずに全てのtable 関連要素をブロック要素にしてみました。当然ですが、全てのセル要素が表示領域幅いっぱいに広がり、縦一列になって並びます。

DEMO

See the Pen Blocked table - Demo of Responsive table by wakamsha (@wakamsha) on CodePen.

幅は%で指定されているので、これならどんなに領域の狭い端末であろうともテーブルがはみ出してしまう事はありませんね。まぁ、これでは情報設計もあったもんじゃないので、全く使いモノにならないわけですが……。

overflow-x を駆使して横スクロールを実現

先ほどのブロック要素になった table ですが、よく見ると最初に thead ブロックが来て、tbody が後に続いています。そして全てのセルの高さが同じとなっています。

ということは、thead ブロックを float して tbody ブロックを回りこませれば、thead と tbody が横並びで揃います。更に tbody 内のセルは tr 要素でグルーピングされています。これら tr 要素をインラインブロック化して横並びにしてやれば、縦方向から横方向に情報の流れが変わった table が出来上がるというわけです

DEMO

See the Pen Blocked & Horizontal table - Demo of Responsive table by wakamsha (@wakamsha) on CodePen.

tbodyブロック内で横スクロールを実現する

横スクロールを実現するには、tbody 要素に対して以下の様に指定してあげれば OK です。

tbody {
  overflow-x: auto;
  white-space: nowrap;
  width: auto;
}

overflow-xに auto を指定することで、横方向のみスクロールが有効になります。そしてwhite-spaceにnowrap と指定すれば、子要素である tr 要素が全て横一列に並ぶようになります。

DEMO

See the Pen Horizontal scroll table - Demo of Responsive table by wakamsha (@wakamsha) on CodePen.

モバイルファースト or デスクトップファースト ?

モバイルファーストの思想に則るならば、CSS はモバイル端末のようなスクリーンサイズの小さい環境に合わせたモノをベースに作成し、PC端末のようなスクリーンサイズの大きい環境へは MediaQueries を使って必要なスタイルを読み込ませるという記述になります。多くの場合はこれでも特に問題は無いのですが、Table の場合はどうでしょうか?先ほどの DEMO で紹介したコードは、Table 関連の要素がデフォルトで持つ display 属性を大幅に書き換えることで成り立っています。モバイルファーストで行くならば、いちどそれらの display 属性を全て打ち消し、その後に MediaQueries で PC 版向けのレイアウト用に再び display 属性をデフォルトのそれに戻すといった記述をしなくてはなりません。なんだか不毛ですよね?

ならばいっそのこと table のレスポンシブデザイン対応に関しては、デスクトップファーストにしてしまった方が余計なコードを書かずに済むので可読性や後のメンテナンス性が損なわれることも無いのではないかと思います

脚注

脚注
1 ここで言うレスポンシブデザインとは、ワンソースで複数スクリーンサイズに対応するテクニックのことを指します。