スクロールしても見出し行が固定されるテーブルの作り方

テーブル
無料ツール
テーブルを自由に作成

行数・列数・枠線・背景色・文字色・セル結合などを設定して、HTMLとCSSを自動生成できます。

テーブル作成ツールを使う
新しいタブで開きます

テーブルの見出し行を固定し、データ部分だけをスクロールできるテーブルの作り方を紹介します。行数の多いテーブルでも、列の項目名を常に確認しながら内容を読み進められるのが特徴です。

今回のテーブルは、「項目名」「内容」「備考」の3列で構成されています。テーブル内を下方向にスクロールすると、青色の見出し行は上部に固定されたまま、項目Aから項目Hまでのデータ行が移動します。上方向へ戻した場合も、見出し行は固定された状態を維持します。

テーブルの表示領域には高さ320pxの上限を設けています。また、画面幅が狭く、テーブル全体が収まらない場合は横方向にもスクロールできます。JavaScriptは使用せず、HTMLとCSSだけで見出し行の固定とスクロール表示を実現しています。

デモ

項目名 内容 備考
項目A サンプル内容A 備考A
項目B サンプル内容B 備考B
項目C サンプル内容C 備考C
項目D サンプル内容D 備考D
項目E サンプル内容E 備考E
項目F サンプル内容F 備考F
項目G サンプル内容G 備考G
項目H サンプル内容H 備考H

テーブル内を上下にスクロールすると、青色の見出し行が上部に固定されたまま、データ行だけがスクロールします。テーブルの表示領域は高さ320pxに制限されており、横幅が足りない場合は横方向にもスクロールできます。

コードをコピーして使おう!

<!DOCTYPE html>
<html lang="ja">
<head>
  <!-- 文字コードの設定 -->
  <meta charset="UTF-8">
  <!-- スマートフォンなどの画面幅に対応 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- ページタイトル -->
  <title>固定ヘッダー付きテーブルを作る方法</title>
  <!-- テーブルのデザインと固定ヘッダーのCSSを読み込む -->
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <!-- 固定ヘッダー付きテーブル全体 -->
  <div class="fixed-table-header_wrap">

    <!-- テーブルをスクロールする領域 -->
    <div class="fixed-table-header_scroll">

      <!-- 固定ヘッダー付きテーブル -->
      <table class="fixed-table-header_table">

        <!-- スクロール時に固定する見出し行 -->
        <thead>
          <tr>
            <th>項目名</th>
            <th>内容</th>
            <th>備考</th>
          </tr>
        </thead>

        <!-- スクロールするデータ行 -->
        <tbody>

          <tr>
            <td>項目A</td>
            <td>サンプル内容A</td>
            <td>備考A</td>
          </tr>

          <tr>
            <td>項目B</td>
            <td>サンプル内容B</td>
            <td>備考B</td>
          </tr>

          <tr>
            <td>項目C</td>
            <td>サンプル内容C</td>
            <td>備考C</td>
          </tr>

          <tr>
            <td>項目D</td>
            <td>サンプル内容D</td>
            <td>備考D</td>
          </tr>

          <tr>
            <td>項目E</td>
            <td>サンプル内容E</td>
            <td>備考E</td>
          </tr>

          <tr>
            <td>項目F</td>
            <td>サンプル内容F</td>
            <td>備考F</td>
          </tr>

          <tr>
            <td>項目G</td>
            <td>サンプル内容G</td>
            <td>備考G</td>
          </tr>

          <tr>
            <td>項目H</td>
            <td>サンプル内容H</td>
            <td>備考H</td>
          </tr>

        </tbody>

      </table>

    </div>

  </div>

</body>
</html>
コードについて 本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。 免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。

コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
A

Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。

InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。

ファイル構成と設置方法

今回のサンプルは、HTMLとCSSの2つのファイルで構成されています。HTMLでは3列の見出しと8行のデータを配置し、CSSではテーブルの表示領域、見出し行の固定、縦横のスクロール、セルのデザインを設定しています。JavaScriptを使用せず、CSSのposition: sticky;で見出し行を固定しています。

sample/
  ├── index.html
  └── style.css

各ファイルの役割
index.htmlには、「項目名」「内容」「備考」の見出し行と、項目Aから項目Hまでのデータ行を記述しています。style.cssでは、見出し行の固定位置、スクロール領域の高さ、テーブルの横幅、セルの余白・枠線・背景色などを設定しています。

設置方法・使い方
「サンプル一式をダウンロード」をクリックしてZIPファイルを保存し、展開してください。sampleフォルダ内のindex.htmlとstyle.cssを同じ階層に配置します。
index.htmlをブラウザで開くとテーブルが表示されます。テーブル内を下方向にスクロールすると、青色の見出し行を固定したままデータ行が移動します。上方向へ戻しても見出し行の固定状態は維持されます。

見出し行を固定する仕組み
style.cssでは、thead内のth要素にposition: sticky;を指定しています。top: 0;を組み合わせることで、見出しセルをスクロール領域の上端に固定しています。

.fixed-table-header_table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #2563eb;
  color: #ffffff;
  font-weight: 700;
}

position: sticky;は、スクロール位置に応じて要素を固定するCSSです。今回の設定では、見出しセルだけが固定され、tbody内のデータ行は通常どおりスクロールします。
z-index: 1;は、見出しセルをデータ行より前面に表示するための指定です。background: #2563eb;を変更すると見出しの背景色を変更でき、color: #ffffff;で文字色を調整できます。

スクロール領域の高さを変更する方法
テーブルを囲む.fixed-table-header_scrollでは、max-height: 320px;で表示領域の最大高さを設定しています。overflow: auto;によって、テーブルが領域を超えた場合にスクロールできるようにしています。

.fixed-table-header_scroll {
  max-height: 320px;
  overflow: auto;
  border: 1px solid #d1d5db;
  border-radius: 8px;
}

max-height: 320px;を400pxに変更すると、一度に表示できるデータ行が増えます。240pxにすると表示領域が低くなり、少ない行数でもスクロールが発生します。
max-heightは最大高さの指定なので、テーブルの内容が少ない場合は320pxより低い高さで表示されます。border-radius: 8px;を変更すると、スクロール領域の角丸も調整できます。

テーブルの横幅と列幅を変更する方法
テーブル全体の最大横幅は.fixed-table-header_wrapで設定しています。テーブル本体にはmin-width: 480px;とtable-layout: fixed;を指定し、3列を均等な横幅で表示しています。

.fixed-table-header_wrap {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
}

.fixed-table-header_table {
  width: 100%;
  min-width: 480px;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  background: #ffffff;
}

max-width: 900px;を変更すると、テーブル全体の最大横幅を調整できます。min-width: 480px;を600pxにすると、狭い画面でもテーブルの最小横幅を600pxに保ちます。
table-layout: fixed;では、現在の3列に横幅が均等に割り当てられます。列ごとに異なる横幅を設定したい場合は、nth-child()で対象の列を指定できます。

/* 1列目の横幅を40%にする */
.fixed-table-header_table th:nth-child(1) {
  width: 40%;
}

このCSSをstyle.cssの末尾に追加すると、1列目の横幅がテーブル全体の40%になります。残りの2列には、残った横幅が割り当てられます。

テーブルの行数と列数を変更する方法
index.htmlでは、theadに見出し行、tbodyにデータ行を配置しています。行を追加する場合は、tbody内のtr要素を複製して内容を書き換えます。

<tr>
  <td>項目I</td>
  <td>サンプル内容I</td>
  <td>備考I</td>
</tr>

この行をtbodyの末尾に追加すると、項目Iが9行目として表示されます。行数が増えても、スクロール領域の最大高さは変わりません。
列を追加する場合は、theadにth要素を追加し、各データ行にも対応するtd要素を追加してください。見出しとデータの列数を揃えることで、同じテーブル構造を維持できます。

セルの余白と背景色を変更する方法
見出しセルとデータセルの内側余白は、padding: 14px 12px;で設定しています。最初の14pxが上下、次の12pxが左右の余白です。

.fixed-table-header_table th,
.fixed-table-header_table td {
  padding: 14px 12px;
  border-right: 1px solid #d1d5db;
  border-bottom: 1px solid #d1d5db;
  text-align: center;
}

上下の余白を18pxに変更すると各行が高くなり、10pxにするとコンパクトになります。text-align: center;をleftに変更すると、セル内の文字を左揃えにできます。
偶数番目のデータ行には、nth-child(even)を使用して薄い青色の背景を設定しています。

.fixed-table-header_table tbody tr:nth-child(even) {
  background: #eff6ff;
}

#eff6ffを変更すると偶数行の背景色を調整できます。背景色を交互に付ける必要がない場合は、このCSSを削除してください。

レスポンシブ対応
テーブル全体にはwidth: 100%;とmax-width: 900px;を設定しているため、設置先の横幅に合わせて表示されます。
テーブル本体にはmin-width: 480px;を指定しているため、スマートフォンなどで表示領域が480pxより狭い場合は、テーブルの最小横幅を維持したまま横スクロールできます。

.fixed-table-header_scroll {
  max-height: 320px;
  overflow: auto;
  border: 1px solid #d1d5db;
  border-radius: 8px;
}

.fixed-table-header_table {
  width: 100%;
  min-width: 480px;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  background: #ffffff;
}

overflow: auto;によって、縦方向と横方向の両方にスクロールできます。横方向に移動しても見出し行はテーブルと一緒に動き、縦方向にスクロールしたときは見出し行が上部に固定されます。
今回のコードはメディアクエリを使用せず、テーブルの横幅とスクロール設定だけで狭い画面に対応しています。


こちらもおすすめ


コメント