tableをレスポンシブでも破綻しないようにする簡易的な1手法

レスポンシブテーブルテスト
レスポンシブテーブルテスト

レスポンシブ設定は便利なものです。1ソースでいろいろな幅の画面(=デバイス)に対応できますから、サイトがブログであればメリットがあります。

WordPressにもレスポンシブ設定が施されているものもありますし、自分でカスタム、あるいは一からテーマ作成すれば同様に利用できるでしょう。

もちろん、WordPressにこだわる必要もなく、何らかの手段で画面サイズをブレークポイントとして可変可能であれば成立します。

が、これは構造部分だけの話で、HTMLタグの種類によっては実現の難しいものもあります。

今回は代表的なtableについて少々。なお、特に目新しい方法ではありませんので、「その程度か」というレベルです。

[2015.1.1追記:「記事に手を入れずに対応する方法」を追記]
[2015.1.1修正:コード内のscrollをautoに変更]

簡易的な方法でtableをレスポンシブ対応させる

考察などは後回しにして手法をご紹介。下記のリンクよりサンプルをご覧頂けます。

簡易なレスポンシブtableサンプル

サンプルのままだと長くなり過ぎるので、下記のコードは形だけのものです。


<div class="table-wrap">
<table>
<tr><th>見出し</th><td>内容</td></tr>
</table>
</div>

続いてcss。


.table-wrap{overflow: auto;}

構造自体は単純です。tableを囲むようにdivを設置し、そのdivoverflow: scroll;を設定しました。

「はみ出た分はスクロールしろ」という設定です。

一応一手間ということで、スクロール出来ることがわかるように、メディアクエリを使って注記を表示させています。

これを入れる場合は、上記の.table-wrapposition:relative;を設定した後で、以下のような追加を行っています。


.table-wrap{overflow: auto; position:relative;}
@media screen and (max-width: 1410px) {
.table-wrap:before{
content: "\008868\00306f\005de6\0053f3\00306b\0030b9\0030af\0030ed\0030fc\0030eb\003067\00304d\00307e\003059"; /* 文字化け対策のためUnicode変換 */
color:#fff;
font-size:12px;
background-color:#e07903;
position: absolute;
top:0px;
border-radius: 5px;
padding: 0.05em 0.5em;
}
}

このように、実際にはレスポンシブというか「テーブルの幅が狭くなりすぎる時の避難策」という感じですが、最低限の「情報が見られること」は確保できているかと思います。

セルの縮小

tableの便利で厄介なところは、自動的に文を折り返してくれるところです。
内包するテキストが「100000」のようなスペースも何もない場合や、white-space:no-wrap;の指定、セルに横幅を指定するなどでなければ、最小は一文字の大きさになります。

そして、1文字になってしまった場合、大抵非常によみにくいtableになります。

前項で挙げている方法は、基本的にセルが一文字なるぐらいまで縮小するリスクを孕んでおり、それを止めるにはmin-widthなどで最小幅を指定するしかありません。

または、セルに最低3文字あればなんとかと判断して、thtdmin-width:3em;のような文字数前提の幅指定をおこなうなどでしょうか。

こういった幅設定を行うと汎用性を欠くので、緊急避難策という観点からは、セル内で横に並ぶ文字数が一文字になってしまう状況も許容しなければならないと思います。

tableの難しさ

レスポンシブで肝になるのは幅によるサイズの変化です。widthを数値で固定さえしていなければ、pタグもliタグも簡単に幅がかえられます。

tableも広げる分にはwidth:100%;の指定で対応できますが、狭める部分に関しては大きな問題があります。

単純な話で、セルが横に長く連なる構造の場合は縮まる幅に限界があるからです。また、rowspancolspanの使用」「tdthの混在」などtableには様々なパターンがあり、そのすべてに1つの設定と方法で対応するのは困難です。

できるだけ簡素に

表が複雑になるのなら、表に手を加えずに簡素になんとかできないかと考えて、前述のサンプルのようにスクロールさせるだけという方法を考えました。

この方法ですと、左端の県名などを固定したいという欲求も生まれるのですが、それを実現するにはまた複雑な方法をとらねばなりません。

どんな表にも使えるという汎用性を求める場合、犠牲にしなければいけない部分はあります。何を優先するかも判断のポイントになるでしょう。

運用時の注意

表を思いついた形でそのまま入力した場合、どう頑張ってもサイトの横幅をこえてしまうtableになる可能性はあります。

それを考えると、表の中身や構造自体に気を使う必要もあるはずです。

入力の度に、文字数を考慮し、内容を削り、表組みの構造を検討する。大きな手間になることは確かですが、例えばB5のチラシにA4と全く同じ情報を同じサイズでいれられるとは思いませんよね?
それと同じです。

サイズにあった内容と構成で考えることは必要です。この努力は結果としてユーザーの利益に寄与(一覧性の向上など)しますし、ムダではありません。

「横一列に表示したい」という重要性もわかりますし、「なぜ表ぐらいサイトの幅に納められないのか」という気持ちもわかりますが、「諦める」という選択肢を忘れない方がよいでしょう。

記事に手を入れずに対応する方法

既にtableを入れ込んだ記事が大量に存在している場合、1記事ごとに編集画面を開いて改修を加えることは現実的ではありません。

その場合はjQueryによる動的な改修手段を用いる方法が考えられます。
具体的には、以下のような記述を追記します。


<script type="text/javascript">
 $(function(){
$('table:not(.table-wrap table)').wrap('<div class="table-wrap"></div>');
  });
</script>

今後手動で追記する可能性がある場合を考えて、予め「.table-wrapを親要素の持たないtable」を指定してから、改めて.table-wraptableをラップする方法です。

tableidなりclassなりがあればそちらを使う方が良いのですが、取り合えずそういうものがない前提の書き方です。

WordPressであればwp_is_mobile()関数を使うほうが良いと思いますが、使わない場合はデバイスのディスプレイの幅で更に限定して以下のようにするのも良いかもしれません。


<script type="text/javascript">
$(document).ready(function() {
if (screen.width <= 768) {
$('table:not(.table-wrap table)').wrap('<div class="table-wrap"></div>');
 }
});
</script>

または、ウィンドウのリサイズに対応する場合はresizeを使って以下のようになるでしょうか。


<script type="text/javascript">
$(window).resize(function() {
if (window.width <= 768) {
$('table:not(.table-wrap table)').wrap('<div class="table-wrap"></div>');
 }
});
</script>

分岐の仕方によってはtableの横幅によってはスクロールさせる必要性がない可能性もあるので、それを考えるなら以下のようになるかと思います。

  1. tableの幅を取得
  2. tableの幅とウィンドウや画面サイズやコンテンツ幅などを比較
  3. ラップ付与の有無を判断
  4. 必要なサイズのtableにだけラップを付与

機会があれば実験してみようと思います。

結び

WordPressなどのテンプレートが使用可能なシステムであれば、比較的簡単にレスポンシブが利用できます。

が、実際に運用しているサイトのいくつかは、表のはみ出しや途切れが見受けられます。その結果主にサイト右側に大きな余白ができたり、表の内容が見られなくなっています。

レスポンシブ設定のテンプレートを使っているから大丈夫、ではない部分はいろいろあるかと思いますので、運用での対応を含めて注意を怠らない方がよいかと思います。

補足

なお、以前の記事でtableの構造から変えるパターンの記事を書いていますので、一応お知らせを。平たく言えば、面倒な手法ですので、ブログなどには全く向かない方法だと思います。

IE7対応のレスポンシブなtableもどき(暫定版)

5人がこの記事を評価

役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。

連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。

コメント欄