おはようございます!株式会社ファストコーディングの働くおかんです。
先日、子どもの学校の時間割表をスマホで見ようとしたら、文字が小さすぎて全然読めなくて。横にスクロールしてもどの列を見ているのかわからなくなる。結局ピンチアウトして拡大して、を繰り返していました。
Webサイトの表も同じ問題が起きるんですよね。PCで見ると綺麗に収まっている料金表や比較表が、スマホだと横にはみ出して読めない。クライアントから「スマホで料金表が切れて読めないんですけど」と連絡が来るのは、コーディングあるあるだと思います。
案件でヒートマップを見ていても、スマホユーザーはテーブルの右側のセルにほとんどたどり着いていないことが多いんです。つまり、スマホでテーブルが読めない=情報が届いていないということなんですよね。
今回は、テーブルのレスポンシブ対応を3つのパターンで紹介します。どのテーブルにどの方式が合うかの判断基準も含めているので、案件で「スマホでテーブルが見づらい」と言われたときの引き出しにしてください。
パターン1:横スクロール方式 ─ 一番シンプルで安全策
最もシンプルな対応が、テーブル全体を横スクロール可能にする方法です。テーブルの構造をまったく変えないので、既存ページへの影響が少なく、「とりあえずの対応」として最も安全です。
<div class="table-scroll-wrapper">
<table class="data-table">
<thead>
<tr>
<th>プラン</th>
<th>月額料金</th>
<th>容量</th>
<th>サポート</th>
<th>バックアップ</th>
</tr>
</thead>
<tbody>
<tr>
<td>ライト</td>
<td>980円</td>
<td>10GB</td>
<td>メールのみ</td>
<td>なし</td>
</tr>
<tr>
<td>スタンダード</td>
<td>2,480円</td>
<td>50GB</td>
<td>メール+チャット</td>
<td>週次</td>
</tr>
<tr>
<td>プレミアム</td>
<td>4,980円</td>
<td>無制限</td>
<td>電話+専任</td>
<td>日次</td>
</tr>
</tbody>
</table>
</div>.table-scroll-wrapper {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.data-table {
width: 100%;
min-width: 600px;
border-collapse: collapse;
}
.data-table th,
.data-table td {
padding: 12px 16px;
border: 1px solid #e5e7eb;
text-align: left;
white-space: nowrap;
}
.data-table thead th {
background: #f9fafb;
font-weight: 600;
}overflow-x: autoで横スクロールを有効にし、min-width: 600pxでテーブルの最小幅を指定しています。スマホ画面(375px程度)より大きい幅を指定することで、テーブルがはみ出してスクロール可能になります。
-webkit-overflow-scrolling: touchは古いiOS Safariでの慣性スクロールを有効にする指定です。最近のブラウザでは不要ですが、入れておいて害はありません。
向いているケース:
- 列数が多い(6列以上)比較表や仕様表
- セルの内容が短いテキスト
- 既存ページに後から対応を入れるとき
注意点: 横スクロールできることにユーザーが気づかない問題があります。テーブルの右端にグラデーションの「影」を付けて、まだ右にコンテンツがあることを示すとUXが改善します。
.table-scroll-wrapper {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
position: relative;
}
.table-scroll-wrapper::after {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 24px;
background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.06));
pointer-events: none;
}夜、子どもが寝た後にこのグラデーションの影を付けてみたら、スクロールに気づく率が明らかに上がりました。ちょっとした工夫ですが効果は大きいです。
なお、overflow-x: autoの要素に直接::afterを付けると、スクロールに追従して影が動いてしまう場合があります。確実に右端に固定したいときは、外側にもう一つ<div>を追加し、外側のdivにposition: relativeと::afterを設定するとうまくいきます。
パターン2:カード型に組み替える方式 ─ 情報量が多いテーブル向け
テーブルの各行をカード型のレイアウトに組み替える方法です。HTMLの構造は<table>のまま、CSSだけで見た目を変えます。
@media (max-width: 768px) {
.card-table thead {
display: none;
}
.card-table tr {
display: block;
margin-bottom: 16px;
border: 1px solid #e5e7eb;
border-radius: 8px;
overflow: hidden;
}
.card-table td {
display: flex;
justify-content: space-between;
padding: 10px 16px;
border: none;
border-bottom: 1px solid #f3f4f6;
}
.card-table td:last-child {
border-bottom: none;
}
.card-table td::before {
content: attr(data-label);
font-weight: 600;
color: #374151;
margin-right: 16px;
}
}ポイントはtd::beforeにattr(data-label)で列名を表示していることです。これにはHTMLの各<td>にdata-label属性を追加する必要があります。
<tr>
<td data-label="プラン">ライト</td>
<td data-label="月額料金">980円</td>
<td data-label="容量">10GB</td>
<td data-label="サポート">メールのみ</td>
<td data-label="バックアップ">なし</td>
</tr>PCでは通常のテーブル、スマホでは1行が1枚のカードになります。各セルの左側に列名(data-label)、右側に値が表示されるので、見出し行がなくても何の値かわかります。
向いているケース:
- 各行の情報量が多い(商品詳細、ユーザー一覧など)
- 行数が少ない(3〜10行程度)
- セルの内容が文章やリンクを含む
注意点: data-labelをHTMLに追加する必要があるため、CMSから出力されるテーブルや、既存ページに後付けするのは手間がかかります。新規制作なら問題ないんですが、改修案件では工数を見積もりに含めてください。
パターン3:列を間引く方式 ─ 「全部見せなくていい」テーブル向け
スマホでは重要な列だけを表示し、残りは「詳細を見る」リンクに逃がす方法です。
.priority-table td:nth-child(4),
.priority-table th:nth-child(4),
.priority-table td:nth-child(5),
.priority-table th:nth-child(5) {
/* PC: 表示 */
}
@media (max-width: 768px) {
.priority-table td:nth-child(4),
.priority-table th:nth-child(4),
.priority-table td:nth-child(5),
.priority-table th:nth-child(5) {
display: none;
}
}これだけだとシンプルすぎるので、優先度の考え方とセットで紹介します。
テーブルの列に「優先度」を付ける考え方が重要です。料金表の場合、「プラン名」と「月額料金」は最優先、「容量」は中優先、「サポート」「バックアップ」は低優先、といった分類です。スマホでは最優先と中優先だけ表示し、低優先はdata属性で制御します。
<table class="priority-table">
<thead>
<tr>
<th data-priority="high">プラン</th>
<th data-priority="high">月額料金</th>
<th data-priority="medium">容量</th>
<th data-priority="low">サポート</th>
<th data-priority="low">バックアップ</th>
</tr>
</thead>
<tbody>
<tr>
<td data-priority="high">ライト</td>
<td data-priority="high">980円</td>
<td data-priority="medium">10GB</td>
<td data-priority="low">メールのみ</td>
<td data-priority="low">なし</td>
</tr>
<!-- 他の行も同様にdata-priorityを付与 -->
</tbody>
</table>data-priority属性は<th>だけでなく<td>にも付与する必要があります。CSSの属性セレクタ[data-priority="low"]は、その属性を持つ要素にしか適用されないためです。
@media (max-width: 768px) {
.priority-table [data-priority="low"] {
display: none;
}
}
@media (max-width: 480px) {
.priority-table [data-priority="medium"] {
display: none;
}
}画面幅768px以下で低優先の列を非表示、480px以下で中優先も非表示。残るのは最優先の「プラン名」と「月額料金」だけです。
向いているケース:
- 列数が多いが、スマホでは全列見せる必要がない
- 詳細ページへの導線がある(テーブルはあくまで概要表示)
- 比較表やスペック表
注意点: 列を非表示にするとSEO上はコンテンツが消えるわけではありません(display: noneはCSSの見た目だけの制御です)。ただし、ユーザーがスマホで「全列を見たい」場合の導線(「すべての項目を見る」ボタンなど)は用意しておくべきです。
どのパターンを選ぶか
クライアントから「スマホでテーブルが見づらい」と言われたとき、最初に確認するのは以下の3点です。
- 列数:5列以上なら横スクロールかカード型。3列以下ならそもそもレスポンシブ問題が起きにくい
- セルの内容:短いテキストなら横スクロール。長い文章や複数行ならカード型
- 改修のしやすさ:既存ページへの後付けなら横スクロール。新規制作ならカード型
実際の案件では、横スクロール方式が最も多く使われています。「とりあえずこれで対応して、必要に応じてカード型に切り替える」という段階的なアプローチがおすすめだと思います。
ある案件では、クライアントから「スマホで料金表が見づらい」と言われて横スクロール方式で対応したところ、「スクロールできることに気づかない」と再修正が入りました。右端のグラデーション影を追加したら「これなら直感的にわかる」と納得してもらえました。最初から影付きで出しておけばよかったです。
まとめ
今回は、テーブルのレスポンシブ対応を3パターンで紹介しました。
- 横スクロール方式は最もシンプルで安全。右端にグラデーション影を付けるとUXが向上する
- カード型方式は情報量の多いテーブルに有効。
data-labelでHTMLへの追記が必要 - 列間引き方式は列数が多い比較表向け。
data-priorityで優先度を管理する
テーブルのレスポンシブ対応は、案件でよく発生する修正依頼です。3つのパターンを引き出しとして持っておけば、テーブルの種類に応じて最適な対応を選べます。「とりあえず横スクロール+影」から始めて、必要に応じてカード型や列間引きに進化させるのがおすすめです。
株式会社ファストコーディングでは、レスポンシブ対応やUI改善のコーディングをお手伝いしています。「既存サイトのスマホ対応を改善したい」「テーブルの見せ方を相談したい」という方は、お問い合わせフォームからお気軽にご連絡ください。

