CSSのテーブルは癖が強いというか、どういう風な仕組みで動いているか分かりにくいCSSにプロパティだと思います。
よくあるのは、レスポンシブ時にはみ出る、、、というやつですね。もともとテーブルとスマホは相性が悪いですが、PCのテーブルをスマホ化する時の方法なども紹介していこうと思います。
CSSのテーブルを使う時に少し思い出してもらえたら嬉しく思います。
基本は勝手に幅を決める
テーブルに複数の列がある場合は、勝手に幅が調整されるというのがデフォルトの仕組みです。中の文字の量によって、勝手に列の幅が決まっているのが分かるかと思います。※ 分かりやすくするためにボーダーと見出しの色だけ入れました。
<table class="tabletest">
<tr><th>見出し</th><th>見出し</th><th>見出し</th></tr>
<tr><td>データ1</td><td>データ2</td><td>データ3</td></tr>
<tr><td>データ1</td><td>長い文字長い文字長い文字長い文字長い文字長い文字長い文字長い文字</td><td>データ3</td></tr>
<tr><td>データ1</td><td>データ2</td><td>データ3</td></tr>
<tr><td>データ1</td><td>データ2</td><td>短い文字短い文字短い文字</td></tr>
</table>
テーブルの列を全て均等にする
テーブルの列を均等にするのは実はとても簡単です。すべての列にwidth
を指定することなく、一発で揃う方法をテーブルは提供してくれています。それが、table-layout: fixed;
になります。
以下のように、table
に指定してあげることで、自動的に均等の列に調整してくれる優れものです。幅(width
)を指定しないと機能しませんので、そこだけ注意してください!
table.tabletest {
border: 1px solid #333;
border-collapse: collapse;
table-layout: fixed;
width: 100%;
}
table.tabletest th,
table.tabletest td {
border: 1px solid #333;
}
テーブルの中のコンテンツに関わらず、すべての列が均等になったことが分かります。
一部は固定で後は均等
さらに、table-layout: fixed;
の素晴らしいところは、幅を指定した列だけにwidth
が反映されるけど、他は均等を保つという性質です。
例えば、以下のように指定することで、最初の列だけ80px
になって、残りの幅(100% – 80px)は他の2つの列で均等に分けられるようになります。
th:first-child {
width: 80px;
}
注意しないといけないのは、幅を指定するのは最初の行だという点です。先ほどのように、CSSで指定してもいいですし、HTMLで直接<th width="80">
書いても機能します。
テーブルの図でいうと、以下の行のどこかに幅を指定する感じになります。
ボーダーを統一する
さっきから、当たり前のように線を1本で出していますが、実はここもデフォルトでは思ったとおりの動作をしてくれない部分になります。何も処理を加えないままにボーダーを入れると以下のようになります。
今の時代にこのタイプのテーブルが使われることはほぼないかと思います。border-collapse: collapse;
という指定をすることで、table
とth
、td
の重なったボーダーを1本としてみなしてるようになるので確実に指定しておきましょう。
ボーダーは3つの要素に付ける
罫線のようにテーブルの全てにボーダーを引きたい場合は、table
とth
、td
にborder
のプロパティを指定してあげます。
table.tabletest {
border: 1px solid #333;
}
table.tabletest th,
table.tabletest td {
border: 1px solid #333;
}
テーブル内の高さの関係
テーブルのセルの中に配置された要素や文字は、vertical-align
の指定に従って配置されます。よく使うのはmiddle
の中央寄せ、top
の上寄せですね。
あまりないと思いますが、全体的に「下寄せ」にしたい場合は、以下のように指定することで対応できます。
table.tabletest th,
table.tabletest td {
vertical-align: bottom;
}
テーブル内の上限の関係を指定できるvertical-align
も覚えておきましょう!
テーブルがはみ出る時の条件と解決策
テーブルを使うと悩まされがちな、ウインドウ幅が小さくなるとはみ出るという問題についてです。まずはどういった時にはみ出るかをおさらいしておきましょう。
おそらく以下のどちらかが原因になっているかと思われます。
テーブルに幅が指定されている場合
分かりやすいのだと、以下のように幅が固定値で指定されている場合ですね。これは、WordPressがTinyMCEのころによく水平スクロールされる事案がありました。
table.tabletest {
width: 768px;
}
セルに改行禁止処理が入っている場合
セルに改行禁止の処理が入っている場合も、ズラーッと水平スクロールされてしまいます。具体的にはth
やtd
にwhite-space: nowrap;
が入っているケースですね。
table.tabletest th,
table.tabletest td {
white-space: nowrap;
}
テーブルがはみ出る場合の解決策
わたしがよく使うのは、テーブルの部分だけ水平スクロールを許可しちゃうバターンです。まずテーブルの外をクラスを付けたdiv
で囲みます。
<div class="tabletest-wrap">
<table class="tabletest">
<tr><th>見出し</th><th>見出し</th><th>見出し</th></tr>
<tr><td>短い文字短い文字短い文字</td><td>データ2</td><td>データ3</td></tr>
<tr><td>データ1</td><td>短い文字短い文字短い文字</td><td>データ3</td></tr>
<tr><td>データ1</td><td>データ2</td><td>データ3</td></tr>
<tr><td>データ1</td><td>データ2</td><td>短い文字短い文字短い文字</td></tr>
</table>
</div>
そして、囲ったdiv
だけはoverflow-x: auto;
として、水平スクロールを許可してあげます。
.tabletest-wrap {
overflow-x: auto;
}
テーブルの部分だけ水平スクロールとなっていることが分かります。
列が多いテーブルはスマホでどう表現するか?
スマホのことが考えられていないPC用のテーブルがあった時に、スマホでどう表現するかはとても悩ましい問題だと思います。解決策と呼べるかは微妙ですが、対応方法としては以下の3つがあります。
水平スクロール
これは先ほど紹介したテーブルが崩れない程度の幅を持たせて、テーブルの部分だけあえて水平スクロールさせる方法です。そんなに考えることがないので、実装する側としてはとても楽です。
列を削る
「スマホにはどうやっても収まらないので、削れる列があったりしませんか?」みたいな確認もしたりします。実はPCの幅の収まりのよさのためだけに入っている列もあったりします。
スマホで入る列は多くても3列だと思うので、この辺まで削れそうならこの方法もありではないでしょうか。
PCをベースで考えると、CSSの書き方としては以下のような感じになるかと思います。
@media screen and (max-width: 767px) {
table.tabletest th:nth-child(2),
table.tabletest td:nth-child(2) {
display: none;
}
}
組み直す
最後は超無理やりな方法です。スマホとPCが完全に別ソースだったころは一般的だったかもしれません。PCの横長のテーブルをスマホの縦に合うようなテーブルに組み直すというものですね。
これはHTMLが2ソースになるので、保守性には欠けますが、デザインは確実にいい感じに作り直すことができます(わたしの例がいい感じ化はさておき…)
HTMLにスマホ用とPC用を書いて、メディアクエリでゴソッと入れ替えるということですね。
おわり
実践的に使う部分に絞ってCSSのテーブルの使い方を紹介してみました。
table-layout: fixed;
での均一の幅であったり、テーブルの外をdiv
で囲んではみ出た時に水平スクロールさせる技など、使えるものがあったら、実際に使ってみてください!