できない.dev

CSSでテーブルを横スクロールさせるには

列の多い表を狭い画面に収めるために、テーブルを overflow-x: auto の要素で包み、テーブル自身には min-width を与えて横スクロールさせる。
ページ全体は横に広がらない。

実行確認済み

実行確認済みは、ブラウザで実際に描画して見た目を確認したものである。

公開:

プレビュー
<div class="table-scroll" tabindex="0" role="region" aria-label="売上テーブル">
  <table class="data">
    <thead>
      <tr>
        <th>商品コード</th>
        <th>商品名</th>
        <th>カテゴリ</th>
        <th>単価</th>
        <th>在庫</th>
        <th>最終更新</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>A-1001</td>
        <td>ワイヤレスマウス</td>
        <td>周辺機器</td>
        <td>3,280</td>
        <td>142</td>
        <td>2026-09-18</td>
      </tr>
      <tr>
        <td>A-1002</td>
        <td>メカニカルキーボード</td>
        <td>周辺機器</td>
        <td>12,800</td>
        <td>37</td>
        <td>2026-09-17</td>
      </tr>
      <tr>
        <td>B-2100</td>
        <td>27インチモニター</td>
        <td>ディスプレイ</td>
        <td>34,800</td>
        <td>8</td>
        <td>2026-09-15</td>
      </tr>
    </tbody>
  </table>
</div>
/* スクロールさせるのは table ではなく、包んでいる側 */
.table-scroll {
  overflow-x: auto;
  border: 1px solid #e4e4e7;
  border-radius: 8px;
}
 
/* キーボードでスクロールできる領域なので、枠を見せる */
.table-scroll:focus-visible {
  outline: 2px solid #0f766e;
  outline-offset: 2px;
}
 
/* min-width が無いと、折り返して縮むだけでスクロールしない */
.data {
  min-width: 560px;
  border-collapse: collapse;
  width: 100%;
  color: #27272a;
  font-family: system-ui;
  font-size: 14px;
}
 
.data th,
.data td {
  padding: 10px 14px;
  border-bottom: 1px solid #e4e4e7;
  text-align: left;
  /* 各セルの折り返しを止めることで、列幅がつぶれるのを防ぐ */
  white-space: nowrap;
}
 
.data thead th {
  background: #f4f4f5;
  font-weight: 600;
}
 
.data tbody tr:last-child td {
  border-bottom: 0;
}

テーブルを overflow-x: auto の要素で包み、テーブル側に min-width を指定して横スクロールさせる。
包む要素が必要なのは、table 自身に overflow を指定しても display: table では効かないためであり、min-width が必要なのは、指定しないとテーブルが親の幅まで縮んでスクロールが発生しないためである。

つまずき

スクロールしないときは、overflow-x を table 自身に書いていないかを確認するとよい。
overflow は display: block などの要素には効くが、display: table の要素には期待どおりに効かない。
もう 1 つの典型は min-width の書き忘れで、この場合テーブルは親の幅まで縮み、セルの中で文字が折り返されるだけになる。
列数 × 最低限読める列幅を見積もって min-width を決めるとよい。

ページ全体が横に広がらない理由

はみ出しているのは包んだ要素の内側なので、はみ出し分はその要素が引き受け、body の幅には影響しない。
もし包む要素の親が幅を持っていない場合や、親に min-width: 100% のような指定がある場合は、はみ出しがそのまま外へ伝わってページ全体が横スクロールすることがある。
スマートフォン幅で確認するときは、document.documentElement.scrollWidth と clientWidth が一致しているかを見ると、ページ側に漏れていないか判断できる。

キーボードで操作できるようにする

スクロールできる領域は、マウスやタッチなら操作できてもキーボードだけでは到達できないことがある。
上の例で tabindex="0" を付けているのはそのためで、タブキーで領域に入ってから矢印キーで横に動かせる。
フォーカスできる要素にしたら、何の領域なのかが分かるように role="region" と aria-label も添える。
既定のフォーカスリングは border-radius の外側に出るので、:focus-visible で outline-offset を調整して見た目を整えている。

この記事は役立ちましたか?