
なんでここでtable使うかなぁ (´・ェ・`)
というレイアウトをよく見かけます。
例えば「商品紹介」「映画などのレビュー」「スポーツのスコア」など。それらがスマートフォンでどんな風に見えるか確認をしていますか?
というわけでtableの使い方と用途別提案など。
tableの廃止属性と代替CSS
旧式の書き方は以下のようなもの。
<table width="横幅" cellpadding="セル内側余白" cellspacing="セル間余白" border="ボーダー関連" background="背景" style="border-collapse: ボーダーの重なり;"> <tbody> <tr> <td align="垂直位置">セル内容</td> <td align="垂直位置">セル内容</td> </tr> </tbody> </table>
赤字部分の属性は 廃止されています。利用中のテンプレートが html5 であるならばこれらの属性を使うべきではありません。
<table style="width: 横幅%; max-width: 最大横幅px; border-spacing: セル間余白px; border-collapse: ボーダーの重なり; border: ボーダー関連; background: 背景関連;"> <tr> <td style="padding: セル内側余白; vertical-align: 垂直位置;">セル内容 <td style="padding: セル内側余白; vertical-align: 垂直位置;">セル内容 </table>
廃止属性は全てCSSに置き換えることができます。
「廃止されたから機能が失われた」のではなく、もともとこれらはCSSでスタイリングするべき内容です。table要素は時と場合によっていろいろなスタイリングを使い分けるべきですので、スタイルシートで決まったスタイルを決めておくことが難しい要素だと言えます。その場合には廃止属性を用いるのではなく、インラインCSS を利用します。htmlの style属性 にCSSを直接記載する方法です。
注) html内の style要素 も「インラインCSS」と呼ばれることがありますが、これとはまた別です。style要素でのCSS指定は Internal CSS (インターナルCSS) と言い換えることができます。
インラインCSS --- style属性
<div class="xxx" style="font-size: 1.2em;"> . . . </div>
インラインCSS(インターナルCSS) --- style要素
<style> .xxx { font-size: 1.2em; } </style>
table関連CSSの説明
省略できるタグ
tbodyの開始タグ・終了タグは省略可能。
tr と td の終了タグは省略可能。
tbody は開始・終了タグともに省略できます。つまり書かなくて良し。trとtdについては終了タグのみ省略可能です。省略しても良いとされるものについては素直に省略するとhtml量を減らせます。ただし 構文に自信が持てる場合のみ。省略したタグはブラウザが補完処理を行います。その場合には「正しいと思われる位置」への補完ですから、コーディング自体があやふやであったり間違っている場合などは逆にその「正しさ」がスタイルを崩す原因になることがあります。
widthプロパティとmax-widthプロパティ
tableの横幅をコントロールするには widthプロパティだけでなく max-widthプロパティを併記する。
スマートフォンでの表示不具合を出さないコツは max-width プロパティの使いこなしです。
table要素にmax-widthプロパティの%単位指定は効きません。 厳密には「table要素にmax-widthプロパティは効かない」のですが、実際にはpx指定であれば効力があります。%指定は不可。widthプロパティには%指定で画面幅との折り合いを、max-widthプロパティにはpx指定で全体幅の制限を行います。div要素などのように width と max-width の 入れ替え不可 は常に頭に入れておくようにします。
また、tableというのは例えtdにサイズを指定しても、全体の都合によってその指定がことごとく破棄される のも特徴です。「tdに width: 150px と書いているのに何故か中の画像が80pxになってしまう…」など。何故そうなるかというと tableだから です。サイズコントロールについては後述。
padding
セル(td要素)内側の余白指定 padding は table ではなく td に指定します。
html4時代はなんでもかんでもtableに追加すれば良かったのですが、本来のCSSプロパティ padding は cellpadding属性のようなtable要素プロパティではありません。paddingは余白を設けたい要素に直接指定しなければ効力はありませんので、従って padding指定はtdへ 行うようにします。
border-spacingプロパティ
tableはあらゆるところに隙間を作ろうとします。
table要素の隙間排除には border-spacing: 0;
td要素の隙間排除には padding: 0
![]() |
上記は実際のtable要素で以下のような内容です。
<table style="width: 200px; height: 200px;"> <tr> <td> <img src="" alt="" width="200" height="200"> </table>
tableのサイズに縦横 200px を指定し、td内の画像にも 200px を指定しています。が、実際の画像のサイズは縦横 194px です。何故6pxも引かれたのか、以下が説明のスクリーンショットです。
tableはデフォルトでこういうスタイリングなので、セル内要素の寸法が微妙に小さくなったり、あるいはセル内に画像を入れて左右辺をぴったりくっつけたくても隙間が空きます。デフォルト = 初期値 なので、何も指定しなければ勝手にそうなります。
![]() |
![]() |
tableへの border-spacing: 0 と tdへの padding: 0 指定で隙間を無くすことができます。
![]() |
![]() |
隙間なし2セルのソース
<table style="width: 100%; max-width: 240px; border-spacing: 0;"> <tr> <td style="padding: 0;"> <img src="" width="120" height="120" alt=""> <td style="padding: 0;"> <img src="" width="120" height="120" alt=""> </table>
隙間のなくし方がわからなくてググりまくるという方が結構多いようなので、この機会に覚えておかれると良いですね。いつかきっと役に立ちます。たぶん。
border-collapseプロパティ
border の重なり指定は border-collapse プロパティで決定。
ボーダークラプスと読みます。
![]() |
![]() |
<table style="width: 100%; max-width: 240px; border: 3px solid green;"> <tr> <td style="border: 3px solid red;"> <img src="" style="width: 100%;" alt=""> <td style="border: 3px solid red;"> <img src="" style="width: 100%;" alt=""> </table>
tableの横幅には240pxを指定してあります。今この2枚の画像の横幅がいくつかわかりますか (´・ω・`)
答え: 106px
左側の画像を使って計算すると、
左tableボーダー(緑)3px + 左border-spacingの2px + 左tdボーダー(赤)3px + 左paddingの1px + 右paddingの1px + 右tdボーダー(赤)3px + 隣接セルとのborder-spacingの1px(セル間2pxなので片セル1px) = 14
120 - 14 = 106
現時点でborderはそれぞれ独立しています。この状態が初期値で border-collapse: separate です。セパレート、つまり「離れる」
![]() |
![]() |
<table style="width: 100%; max-width: 240px; border: 3px solid green; border-collapse: collapse;">
<tr>
<td style="border: 3px solid red;">
<img src="" style="width: 100%;" alt="">
<td style="border: 3px solid red;">
<img src="" style="width: 100%;quot; alt="">
</table>
tableへの緑ボーダー3px指定はそのままですが、レンダリングでは緑ボーダーは消えています。tableのボーダーとtdのボーダーが重なったから です。
border-collapse: collapse;collapse値を指定すると隣接する要素のボーダー同士が重なります。クラプス、つまり「折りたたむ」tableボーダーでなくtdのボーダーが表示されている様子もわかりますね。そしてborder-spacingが無くなっていることもわかります。border-spacingはボーダーが表示されている場合は隣接セルのボーダーとの距離なので、そのボーダーが重なるのですから当然無くなります。
ボーダーの数値が異なる場合。
![]() |
![]() |
tableのボーダーを3pxから5pxに変更しました。太い方が細い方を吸収しています。
ここまでのまとめ「重要プロパティ」
border-spacing --- tableへ指定「セル間余白」
border-collapse --- tableへ指定「ボーダーの重なり(折りたたみ)」
padding --- tdへ指定「セル内側余白」
上記3つをしっかり覚えておくことがtable利用の鍵になります。ここからは具体的なケーススタディです。
tableのサイズをコントロールしきれていない例
パソコンの見た目
BAD
GOOD
BAD 問題点
・画像とテキストの距離が定まらない
スマートフォンの見た目(横414px)
BAD
GOOD
BAD 問題点
・スマホの画面幅いっぱい使い切っていない
・画像とテキストのバランスが悪い
BAD html
<table style="width: 75%;"> <tbody> <tr> <td style="vertical-align: top;"> <a><img src="" alt=""></a> </td> <td style="padding-left: 10px; vertical-align: top;"> <a>The Glass Menagerie ガラスの動物園</a><br> (1944年初版)<br> Tennessee Williams 著<br> <br> <a>商品詳細を見る</a><br> 興味のある方今すぐほしい方は <br> Axxxxn から購入もできます!! </td> </tr> </tbody> </table>
GOOD html
<table style="table-layout: fixed; border-spacing: 0; width: 100%; max-width: 500px;"> <tr> <td style="vertical-align: top; width: 117px; padding: 0;"> <a><img src="" alt=""></a> </td> <td style="vertical-align: top; padding: 0 0 0 15px;"> <a>The Glass Menagerie ガラスの動物園</a> <br>(1944年初版)<br> Tennessee Williams 著<br> <br> <a>商品詳細を見る</a><br> 興味のある方今すぐほしい方は <br> Axxxxn から購入もできます!! </td> </tr> </table>
BAD htmlはFC2運営が自社ブロガーの著書を紹介する際に用いているソース内容に近いものです(全く同じではありません)
パソコンでの見た目しか考えていないので width: 75% と指定してしまってますが、スマートフォンで横幅が75%ということは、414pxデバイスならば290弱しかありませんので縦伸びして非常に不格好です。スマートフォンでは横幅を100%使い切る内容にしておくのが望ましいでしょう。
tableのセル(td)は普通に横幅を指定しただけでは 全体幅の都合によって指定が無視されてしまう というのは既に述べました。横幅を固定したい場合はセルにwidthを px単位 で設け、親要素のtableに table-layout: fixed を指定します。fixed値を指定し、セルに横幅が記されていない場合には全てのセルが 等分 になってしまいますが、セルに横幅がある場合にはその指定サイズを守るようになります。
tableレイアウトにすべきでない場面
パソコンの見た目
GOOD
GOOD
スマートフォンの見た目(横414px)
BAD
GOOD
BAD 問題点
・ひどすぎ
BAD html
<table style="table-layout: fixed; width: 100%; margin-top: 40px; border-spacing: 0;"> <tr> <td style="vertical-align: top; width: 200px; padding: 0;"> <img src="" alt=""> </td> <td style="vertical-align: top; padding: 0 0 0 15px;"> オディロンは、1840年4月20日、南フランスの大都市ボルドーで生まれた。 〜省略〜 なお、弟のガストン・ルドン(英語版)は長じて建築家となり、世に作品を残している。 </td> </tr> </table>
GOOD html
<div style="overflow: hidden;"> <img src="" alt="" style="float: left; width: 40%; width: 200px; margin-right: 15px;"> <p style="margin: 0;"> オディロンは、1840年4月20日、南フランスの大都市ボルドーで生まれた。 〜省略〜 なお、弟のガストン・ルドン(英語版)は長じて建築家となり、世に作品を残している。 </p> </div>
これはもうtableの書き方云々ではなく、tableを選ぶべきではなかった というパターンです。つまり選択のミス。
横に並べたもの同士の高さの差が顕著になることが明らかなので float を利用する場面です。
float要素へのwidth指定は スマートフォンの見た目 を想定して決めます。やはりここでも width プロパティと max-width プロパティのダブル使いです。
横に並べたい → tableを使う
と考える方がとても多いのですが、そもそもtableは狭い画面とは非常に相性が悪い です。それを踏まえ、まずは手法の選択から考えるようにしましょう。
レスポンシブか横スクロールか
tableに width: 100% が指定されている場合。%という指定は相対値ですから、必ず参照する要素があります。通常は「記事の横幅」です。テンプレートがレスポンシブデザインかスマホ専用版かに関わらず、スマホではシングルカラムが基本ですから、スマホでの記事幅はスマホの画面幅(ビューポート)とほぼ同等になります。
パソコンでの width: 100% は900pxあるいは1000pxかもしれません。スマホでの width: 100% は 414px〜320px弱になります。掲載したいtable要素が 400px程度の画面に収めてもすんなり閲覧ができるかどうか です。
あるいは「widthとmax-widthを併用するのが基本」と書きましたが、旧態然で <table width="800"> といった書き方をしてしまっている方も多いのではないでしょうか。width属性では単位が省略されていますが、省略単位は px です。つまり 絶対値 なんですね。相対値はなにかを参照して自身の幅を決めますが、絶対値は他要素を参照しません。つまり画面幅が400pxしかなくとも800pxで表示を行います。要するに overflow (オーバーフロー, 溢れ, はみ出し) ですね。これは絶対避けなければいけませんね。スマホユーザーにとっては不都合極まりないからです(画面ブレ)
はみ出す例
記事の領域を知る(記事幅の把握) --- 仮に800pxとする
↓
800pxをセル数で割る --- 800 ÷ 10 = 80
↓
tableに width="800" を記載、tdに width="80" と記載
↓
スマホではみ出す
サンプルはスマホどころかパソコンでもはみ出してますが、わかりやすくするためにワザとそうしています。多くの方はこの状態に「ならないように」と考えて「いるつもりで」パソコンの記事幅を基準にセルのサイズを算出しようとします。記事幅の把握など不要ですし、計算なんてしちゃダメです。計算するからはみ出すんです。どのみちスマホ画面は400px程度。パソコンのことしか考えていないから無駄な計算をした挙げ句にスマホでめちゃくちゃなレイアウトになる んです。
はみ出さないものの見た目がよろしくない例
そこで width と max-width の併記でもってはみ出させないよう対処したとします。以下がスマホでの様子。
何がしたいねん。 でもよく見かけます(笑)
こういう場合は素直に 横スクロール を選んだ方が良いですね。こんな感じです。
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Rain Dogs Tom Waits |
The Beat Becomes a Sound Late Night Alumni |
The Sickness Disturbed |
Nothing to Lose Billy Talent |
Little L Jamiroquai |
I Love College Asher Roth |
Rage For Order Queensryche |
Keep Myself Alive Get Scared |
Around The World Red Hot Chilli Peppers |
9 Crimes Damien Rice |
横スクロールソース
<div style="position: relative; overflow-x: auto; padding: 30px 0; -webkit-overflow-scrolling: touch; white-space: nowrap;"> <table style="table-layout: fixed; width: 100%; border: 1px solid rgb(200,200,200); border-collapse: collapse; background-color: white; color: rgb(51,51,51); text-align: center;"> <tr> <td style="width: 130px; padding: 5px; border: 1px solid rgb(200,200,200); background: white;"> <img src="" alt=""> <td style="width: 130px; padding: 5px; border: 1px solid rgb(200,200,200); background: white;"> <img src="" alt=""> <td style="width: 130px; padding: 5px; border: 1px solid rgb(200,200,200); background: white;"> <img src="" alt=""> <tr> <td style="padding: 5px; border: 1px solid rgb(200,200,200); white-space: normal; background: white;"> テキスト <td style="padding: 5px; border: 1px solid rgb(200,200,200); white-space: normal; background: white;"> テキスト <td style="padding: 5px; border: 1px solid rgb(200,200,200); white-space: normal; background: white;"> テキスト </table> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 554.625 554.625" style="width: 40px;" class="fade-reverse" fill="currentColor"> <path d="M478.125,229.5c-11.475,0-21.037,3.825-28.688,9.562l0,0c0-26.775-21.037-47.812-47.812-47.812 c-11.475,0-22.95,3.825-32.513,11.475c-7.649-19.125-24.862-30.6-43.987-30.6c-11.475,0-21.037,3.825-28.688,9.562V86.062 c0-26.775-21.037-47.812-47.812-47.812c-22.95,0-42.075,17.212-45.9,38.25H66.938l61.2-61.2L114.75,0L28.688,86.062l86.062,86.062 l15.3-15.3l-63.112-61.2h133.875v160.65c-38.25-34.425-80.325-61.2-107.1-34.425c-38.25,38.25,42.075,112.837,103.275,225.675 c43.988,78.412,105.188,107.1,166.388,107.1c89.888,0,162.562-72.675,162.562-162.562v-114.75 C525.938,250.538,504.9,229.5,478.125,229.5z M506.812,319.388v72.675c0,74.588-65.025,143.438-143.438,143.438 c-72.675,0-114.75-40.162-149.175-95.625c-74.588-126.225-128.138-183.6-107.1-204.638c21.038-21.037,72.675,24.863,112.837,66.938 V86.062c0-15.3,13.388-28.688,28.688-28.688s28.688,13.388,28.688,28.688v200.812h19.125v-66.938 c0-15.3,13.388-28.688,28.688-28.688s28.688,13.388,28.688,28.688v47.812h19.125v-28.688c0-15.3,13.388-28.688,28.688-28.688 s28.688,13.388,28.688,28.688v47.812h19.125v-9.562c0-15.3,13.388-28.688,28.688-28.688s28.688,13.388,28.688,28.688V319.388z"/> </svg> </div> <script> var styleElm = document.createElement('style'); styleElm.innerText = '@keyframes fade-reverse{0%{transform:translateX(50%);opacity:0}50%{transform:translateX(0%);opacity:1}100%{transform:translateX(-50%);opacity:0}}.fade-reverse{position:absolute;top:0;left:15px;animation:fade-reverse 1.8s linear infinite}'; document.getElementsByTagName('head').item(0).appendChild(styleElm); </script>
スワイプアイコンはオマケで付けてあります。重要プロパティは緑の部位。
まずdiv要素。table全体をdivで囲い、divに white-space: nowrap を指定。これを指定することでtableのshrink(縮む)を不可にします。同じくdivに overflow-x: auto を指定。これで横スクロールバーが出るようになります(auto値は横幅が超過するまで出ません)
-webkit-overflow-scrolling: touch はiPhoneで感性スクロールを効かせるために必要です。
position: relative はabsolute配置するスワイプアイコンの基点にするためです。スワイプアイコンのアニメーションは使用頻度が低いでしょうからJSでスタイルを差し込む方法が良いでしょう(利用頻度が高い場合はスタイルシートへ)
続いてtable要素。
サンプルの場合は画像のサイズに合わせた方が綺麗なので、セル横幅は画像サイズを最優先します。何度も書きますがtableのセルは得て勝手にサイズが変えられてしまいますので、table-layout: fixed でそれを防止します。
下段はテキストです。テキストは折返しが効きますので、画像の横幅を超えないよう white-space: normal を指定します。div要素に white-space: nowrap を指定しており、このプロパティは継承しますので normal 指定をして戻します。でないと折り返しません。
td要素には面倒でもbackgroundの色指定をします。スクロールボックス内で背景色が途切れてしまうのを防ぐためです。
tableの横スクロールは少しだけテクニックが必要ですが、サンプルソースをひな形として取っておくと応用が効くと思います。
まとめ
table要素はtrやtdなどの部品がありますのでややこしいですね。
そしてtableの持つ shrink to fit が他要素、例えばdiv要素などと真逆の性質なので同じ感覚で使っているとハマります。FC2ブロガーさんでtableを利用しているほとんどのユーザーがスマホで閲覧困難な状況に陥っています。どれもこれも「慣れ」と「要領」なので、雛形を活かしてみてください。
There are no comments yet.