ホームへ

【CSS】tableのthを固定して縦横スクロールさせる方法

タイトル1-1 タイトル1-2 タイトル1-3 タイトル1-4 タイトル1-5 タイトル1-6 タイトル1-7 タイトル1-8 タイトル1-9 タイトル1-10 タイトル1-11 タイトル1-12 タイトル1-13 タイトル1-14 タイトル1-15 タイトル1-16
タイトル2 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル3 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル4 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル5 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル6 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル7 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル

スマホ画面のように小さな範囲でも表を見せたいときがあるでしょう。

小さな範囲で見せるにはスクロールさせるしかありません。

そしてスクロールするならタイトルを固定させたほうがわかりやすいことが多いでしょう。

tableのthを固定して縦横スクロールさせる方法を解説します。

スクロールさせる方法

親要素にoverflow: auto

tableの上にdivなど親要素を用意します。コレがスクロールの窓となります。

この親要素にoverflow: autoまたはoverflow: scrollを指定します。

autoを指定するとtableが親要素より小さいときはスクロールバーが表示されなくなります。

逆にscrollを指定するとtableが親要素より小さくてもスクロールバーが表示されます。

この親要素がスクロールの窓となるためwidthやheightで窓枠の範囲を指定しましょう。

tableの幅(高さ)を親要素より大きくする

tableにwidthやheightを指定

tableは何も指定しないと親要素の横幅を超えることはありません。

tableのサイズを親要素より大きく指定しましょう。

列数やtdの幅が決まっているときはtableにwidthを指定しましょう。

なおtdにwidthを指定してもtableの横幅を親要素以上に広げることはできません。

縦スクロールしたい場合、heightを指定してもいいですが、単純に行数が多ければ高さは広がるためheightは未指定でもいいでしょう。

tdにwhite-space: nowrapを指定

white-space: nowrapを指定すると自動改行されなくなります。

これを指定するとtdを押し広げてtableの横幅を広げることができます。

列が増える、tdの横幅を指定したくないときはtdにwhite-space: nowrapを指定しましょう。

thを固定させる方法

thにposition: sticky

固定させたい要素に「position: sticky」「top: 0」「left: 0」を指定します。

th{
    position: sticky;
    top: 0;
    left: 0;
}

「position: sticky」を指定するとスクロールされ画面から外に行くとき、外に行かず内側に留まります。

親要素にoverflow: autoがあるとそこが留まるラインとなります。

「position: sticky」は縦スクロールだけでなく横スクロールでも固定できます。

th固定のコツ

thに背景色を指定

スクロールするとthが固定されますが、tdはスクロールされます。

当然thとtdが重なるわけですが、thの背景色を指定しないと重なったtdが透けて見えます。

thにbackgroundを指定しましょう。

th{
    background: #f2f2f2;
}

左上のthを手前にする

positionで要素が重なると後述されたhtmlタグが上に乗ります。

これでは左側のthで右側のthが隠れてしまいます。

これを防ぐため左上のthつまり一行目一列目のthに「z-index: 1」を指定します。

z-indexを指定すると重なり順を指定できます。

一行目一列目のthは「tr:first-child th:first-child」と指定します。

tr:first-child th:first-child{
    z-index: 1;
}

borderもthと固定する

thを固定した場合、線も一緒に固定されて欲しいですよね。

よってthにborderを指定します。

まず各th各tdの下と右に線を指定します。

続いて一行目のthの上、一列目のthの左に線を指定します。

td,th{
    border-right: 1px solid #999;
    border-bottom: 1px solid #999;
}
.example tr:first-child th{
    border-top: 1px solid #999;
}
.example th:first-child{
    border-left: 1px solid #999;
}

tableに線を指定するとスクロールしたときに線が流れてしまうためthに指定しましょう。

また各th、各tdの上と左に線を指定するとスクロールしたときthとtdの境界線の線が流れてしまいます。

tableスクロール完成形

タイトル1-1 タイトル1-2 タイトル1-3 タイトル1-4 タイトル1-5 タイトル1-6 タイトル1-7 タイトル1-8 タイトル1-9 タイトル1-10 タイトル1-11 タイトル1-12 タイトル1-13 タイトル1-14 タイトル1-15 タイトル1-16
タイトル2 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル3 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル4 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル5 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル6 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
タイトル7 セル セル セル セル セル セル セル セル セル セル セル セル セル セル セル
<style>
.example{
    overflow: auto;
    width: 100%;
    height: 200px;
}
.example table{
    margin: 0;
    border-spacing: 0;

}
.example td{
    white-space: nowrap;
    border-right: 1px solid #999;
    border-bottom: 1px solid #999;
    background: #FFF;
    padding: 5px;
}
.example th{
    white-space: nowrap;
    border-right: 1px solid #999;
    border-bottom: 1px solid #999;
    background: #f2f2f2;
    position: sticky;
    top: 0;
    left: 0;
}
.example tr:first-child th{
    border-top: 1px solid #999;
}
.example th:first-child{
    border-left: 1px solid #999;
}
.example tr:first-child th:first-child{
    z-index: 1;
}
</style>
<div class="example">
    <table>
        <tr>
            <th>タイトル1-1</th>
            <th>タイトル1-2</th>
            <th>タイトル1-3</th>
            <th>タイトル1-4</th>
            <th>タイトル1-5</th>
            <th>タイトル1-6</th>
            <th>タイトル1-7</th>
            <th>タイトル1-8</th>
            <th>タイトル1-9</th>
            <th>タイトル1-10</th>
            <th>タイトル1-11</th>
            <th>タイトル1-12</th>
            <th>タイトル1-13</th>
            <th>タイトル1-14</th>
            <th>タイトル1-15</th>
            <th>タイトル1-16</th>
        </tr>
        <tr>
            <th>タイトル2</th>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
        </tr>
        <tr>
            <th>タイトル3</th>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
        </tr>
        <tr>
            <th>タイトル4</th>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
        </tr>
        <tr>
            <th>タイトル5</th>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
        </tr>
        <tr>
            <th>タイトル6</th>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
        </tr>
        <tr>
            <th>タイトル7</th>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
            <td>セル</td>
        </tr>
    </table>
</div>

【まとめ】tableのthを固定して縦横スクロールさせる方法

スクロールさせる方法

親要素にoverflow: auto

tableにwidthやheightを指定するかtdにwhite-space: nowrapを指定

thを固定させる方法

「position: sticky」「top: 0」「left: 0」を指定

thに背景色を指定、左上のthを手前にする、borderもthと固定する

以上、tableのthを固定して縦横スクロールさせる方法でした。

マンガで読める関連記事