tableのヘッダーを固定する方法2つ[position: stickyの活用とGrid.jsの場合]

tableのヘッダーを固定する方法2つ[position: stickyの活用とGrid.jsの場合]
Webサイトの制作案件で、地味な様ですが、それでいて
結構出てくる頻度が多かったりする「テーブル要素」による表組み。
何か複数の項目を扱っていたり、それらを比較したり、といったコンテンツのあるWebサイトの場合、
けっこう出会う頻度が高いと思います。

案件によっては
「このテーブル、アタマの1行だけ固定して!」
というようなオーダーを頂くこと、実際の制作案件では結構、あると思います。

今回はタイトルの通り、そんな時に使うことができる
「table要素のヘッダーを固定する方法」についての記事になります。

↑このように、table内のいちばん先頭の1行を、position: sticky; を使って固定させる方法についての記事です。後半は、Grid.jsを使っている場合の固定方法についてもご紹介しています。

まずは結論から。position: sticky; を使用する方法

次の様な構造のテーブル要素があったとします。
列が4列、行が8行ある、
縦軸にA B C
横軸に項目01〜07
を比較することができる想定のテーブルです。

<div class="table-container">
    <table class="table-element">
      <thead class="table-header-group">
        <tr class="table-row">
          <th class="table-header"></th>
          <th class="table-header">A</th>
          <th class="table-header">B</th>
          <th class="table-header">C</th>
        </tr>
      </thead>
      <tbody class="table-body">
        <tr class="table-row">
          <th class="table-header">項目01</th>
          <td class="table-data"></td>
          <td class="table-data"></td>
          <td class="table-data"></td>
        </tr>
        <tr class="table-row">
          <th class="table-header">項目02</th>
          <td class="table-data"></td>
          <td class="table-data"></td>
          <td class="table-data"></td>
        </tr>
        <tr class="table-row">
          <th class="table-header">項目03</th>
          <td class="table-data"></td>
          <td class="table-data"></td>
          <td class="table-data"></td>
        </tr>
        <tr class="table-row">
          <th class="table-header">項目04</th>
          <td class="table-data"></td>
          <td class="table-data"></td>
          <td class="table-data"></td>
        </tr>
        <tr class="table-row">
          <th class="table-header">項目05</th>
          <td class="table-data"></td>
          <td class="table-data"></td>
          <td class="table-data"></td>
        </tr>
        <tr class="table-row">
          <th class="table-header">項目06</th>
          <td class="table-data"></td>
          <td class="table-data"></td>
          <td class="table-data"></td>
        </tr>
        <tr class="table-row">
          <th class="table-header">項目07</th>
          <td class="table-data"></td>
          <td class="table-data"></td>
          <td class="table-data"></td>
        </tr>
      </tbody>
    </table>
  </div>

↑上記の構造のテーブルがあったとして、ここに、次の様なcssを適用してあげると、
スクロール時にテーブルのヘッダ(先頭のA B Cの行)を固定させることができます。
※ブラウザのデフォルトスタイルをリセットするcssは、既に適用されている前提で書いています。

    .table-container {
      border: 1px solid #ebebeb;
      height: 300px;
      margin: 2rem auto;
      -ms-overflow-style: none;
      overflow: scroll;
      scrollbar-width: none;
      width: fit-content;
    }
    .table-container::-webkit-scrollbar {
      display: none;
    }
    .table-element {
      border-collapse: separate;
      border-spacing: 0;
      font-size: .75rem;
      height: 100%;
    }
    .table-header-group {
      border-bottom: 1px solid #ebebeb;
      box-shadow: 0 3px 10px -3px rgba(0, 0, 0, .15);
      height: 40px;
      position: sticky;
      top: 0;
      width: 100%;
      z-index: 10;
    }
    .table-header-group .table-header {
      background: rgba(245, 245, 245, 1);
      height: 40px;
    }
    .table-body .table-header {
      background: rgba(215, 215, 215, 1);
      width: 100px;
    }
    .table-body .table-row:nth-of-type(even) {
      background: rgba(240, 240, 240, 1);
    }
    .table-data {
      height: 60px;
      min-width: 200px;
    }
    .table-header,
    .table-data {
      border-bottom: 1px solid #ebebeb;
    }
    .table-data {
      border-right: 1px solid #ebebeb;
    }
    .table-body .table-row:last-of-type .table-header {
      border-bottom: none;
    }
    .table-data:last-of-type {
      border-right: none;
    }

↑ポイントとしては、
thead 要素に
23行目で 適用している
position: sticky; と、
それを有効にするために
その親要素達に必要なプロパティを指定している点です。

以前の記事でも書きましたが、position: sticky; を有効にするために必要な確認点としては

・親要素にheightを指定すること
直前の親要素にoverflowが設定されていないこと(←この条件は複雑なので後日加筆予定です。少なくとも全体を包括する親要素には指定)
・position: sticky; を指定した要素に top, left 等の位置指定をしていること

等です。

上記のcssの記述で、スクロール時にテーブルのヘッダ(先頭の A B C が入っている1行)を固定することが可能です。

【Premium特典】コード全体をダウンロード

ここまで、「tableのヘッダを固定する方法」についての記事をご紹介してきましたが、理解を深めるには
実際に動いている実物を見てみるのが一番早いかと思います。

tedate Premium にご登録いただくと、当記事で扱った内容のサンプルのhtmlファイルをダウンロードいただけます。
こちらのダウンロードファイルでは、冒頭の動画にあるような、「tableのヘッダが固定」されている実際の状態を確認いただけます。

tedate Premiumとは?

「tedate Premium」 とは、tedate.jp 閲覧時に掲示される
広告を非表示にする事ができたり、会員限定記事が閲覧可能になる、
月額制の会員機能です。

ログイン頂くと、この記事のサンプルデータがダウンロードできます。
ダウンロードするには、tedate Premiumにご登録ください。
登録済みの方のログインページはこちら
tedate Premiumのご説明・新規ご登録は次のリンクよりお進みください。
tedate Premium のご紹介


ダウンロードデータ更新日:2023年1月16日。※随時アップデート予定です。

Grid.jsの場合

余談として、当サイトでよくご紹介している
とても優秀なtableライブラリ「Grid.js」で、ヘッダの先頭1行を固定する方法です。

この場合は至って簡単で、次の様に記述します。

<script>
new gridjs.Grid({
  columns: ['名前', 'ジャンル', '素晴らしさ'],
  data: [
    ['Vue', 'Frontend Framework', '★★★★★'],
    ['Vuetify', 'UI Framework', '★★★★★'],
    ['React', 'Frontend Framework', '★★★★★'],
    ['Gatsby', 'Static Site Generator', '★★★★★'],
    ['Grid', 'Great Table Library', '★★★★★']
  ],
  sort: true,
  fixedHeader: true,
  height: '300px',
}).render(document.getElementById('gridContainer'));
</script>

↑…何とも簡単なのですが、
12行目にある様に、 fixedHeader オプションを true にしておくだけです。
たったこれだけで、ヘッダ固定のテーブルが作成できます。やはりGrid.js、とても優秀なライブラリですよね。

この記事のまとめ

今回は、とても手短ながら
「tableのヘッダーを固定する方法」について書きました。

2つ目のセクションで書いた様に、
Grid.jsを使用している場合はとてもお手軽なのですが

最初のセクションでご紹介したように、地道に
position: sticky;
で固定する方法を覚えておくと、いろいろな場面で
応用が効く手法かと思いますので、地味ながらも覚えておくときっと役に立つことかと思います。

この記事が皆さんのより良いWeb制作体験につながれば、嬉しく思います。

※この記事は内容の品質向上を目的に、随時更新を行う場合があります。

この記事をシェアする: