本記事は執筆時点(2024年04月12日)の情報をベースにしております。掲載している情報が最新ではない可能性がありますので何卒ご容赦ください。
stickyを使えばテーブルの先頭行や先頭列を簡単に固定できる
情報量の多い表を作る場合は、スクロールした時に項目名などの行や列は固定させておいたほうが見やすくなります。
positionプロパティの「sticky」を使えば、CSSだけで行も列も簡単に固定することができるのでご紹介します。
position:stickyとは?
CSSのposition:sticky;は、要素をスクロールに応じて親要素内に固定表示できるプロパティです。
「absolute」や「fixed」と異なり、スクロール開始位置まで要素を通常通り表示し、指定位置に達すると親要素内に固定するという特徴があります。
先頭行を固定するテーブルの作り方
はじめに紹介するのは、テーブルが上下にスクロールされたときに先頭行を固定して表示する方法です。
出来上がりのイメージは以下の通りです。
まずHTMLでテーブルを作成します。テーブルをスクロールできるようにするのでdiv要素「class="wrapper"」で囲みます。
項目名を記載する先頭行はtheadを使って記述します。
HTML
<div class="wrapper">
<table class="myTbl fixedThead">
<thead>
<tr>
<th>項目A</th>
<th>項目B</th>
<th>項目C</th>
<th>項目D</th>
<th>項目E</th>
</tr>
</thead>
<tbody>
<tr>
<td>セルA1</td>
<td>セルB1</td>
<td>セルC1</td>
<td>セルD1</td>
<td>セルE1</td>
</tr>
<!--省略-->
<tr>
<td>セルA7</td>
<td>セルB7</td>
<td>セルC7</td>
<td>セルD7</td>
<td>セルE7</td>
</tr>
</tbody>
</table>
</div><!--end wrapper-->
CSSでtheadにposition:stickyを指定して固定表示を実現します。
このときスクロールすると上下に隙間が生じて下に入り込んだ要素が少し見えてしまうので、border-topとborder-bottomを指定した疑似要素を固定して隙間を埋めます。
なおテーブルの親要素である「wrapper」にoverflow:scrollと幅や高さを指定することでテーブルがスクロールできるようになります。
※テーブルのbackgroundやborderなどのスタイルは省略しています。
CSS
.wrapper{
width:600px;
height:250px;
border:solid 2px #999;
overflow:scroll;
margin-bottom:15px;
}
/*thead固定*/
.fixedThead thead{
position:sticky;
top:0;
left:0;
z-index:1;
}
/*スクロール時に上にできる隙間を埋める*/
.fixedThead thead::before{
content:"";
width: 100%;
height:100%;
border-top:solid 1px #999;
position: absolute;
top:0px;
left:0;
z-index:-1;
}
/*スクロール時に下にできる隙間を埋める*/
.fixedThead thead::after{
content:"";
width: 100%;
height:100%;
border-bottom:solid 2px #999;
position: absolute;
top:-2px;
left:0;
z-index:-1;
}
先頭列を固定するテーブルの作り方
続いてはテーブルが左右にスクロールされたときに先頭列を左端に固定して表示する方法です。
出来上がりのイメージは以下の通りです。
さきほどのHTMLに固定用の列を新たに1行追加します。
HTML
<div class="wrapper">
<table class="myTbl fixedCol">
<thead>
<tr>
<th>row/col</th>
<th>項目A</th>
<th>項目B</th>
<th>項目C</th>
<th>項目D</th>
<th>項目E</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td>セルA1</td>
<td>セルB1</td>
<td>セルC1</td>
<td>セルD1</td>
<td>セルE1</td>
</tr>
<!--省略-->
<tr>
<th>7</th>
<td>セルA7</td>
<td>セルB7</td>
<td>セルC7</td>
<td>セルD7</td>
<td>セルE7</td>
</tr>
</tbody>
</table>
</div><!--end wrapper-->
先頭列の場合は、最初の要素のみに限定できる疑似クラス「first-child」を利用してstickyを適用させます。
今回はスクロールすると左右に隙間が生じて下に入り込んだ要素が少し見えてしまうので、border-leftとborder-rightを指定した疑似要素を固定して隙間を埋めます。
なお親要素である「wrapper」を上回る幅をテーブルに指定することで横にスクロールできるようになります。
CSS
.wrapper{
width:600px;
height:250px;
border:solid 2px #999;
overflow:scroll;
margin-bottom:15px;
}
.fixedCol{
width:900px;
}
/*先頭列固定*/
.fixedCol th:first-child{
width:30px;
position:sticky;
left:0;
z-index:0;
}
/*スクロール時に左にできる隙間を埋める*/
.fixedCol th:first-child::before{
content:"";
width: 100%;
height:100%;
border-left:solid 2px #999;
position: absolute;
top:0px;
left:-2px;
z-index:-1;
}
/*スクロール時に右にできる隙間を埋める*/
.fixedCol th:first-child::after{
content:"";
width: 100%;
height:100%;
border-right:solid 2px #999;
position: absolute;
top:0px;
right:-2px;
z-index:-1;
}
先頭行と先頭列を固定するテーブルの作り方
最後はテーブルの先頭行と先頭列の両方を固定する方法です。
テーブルのクラスに「fixedThead」と「fixedCol」の両方を追加すれば以下のような動きを実現できます。
まとめ
以上がCSSのstickyを使用してテーブルの先頭行や先頭列を固定する方法です。
スマホやタブレットなどのタッチデバイスではスクロールバーが表示されないので「スクロールできます」という案内も添えた方がより親切かもしれません。

横スクロール可能なことを示すヒントを表示するJavascriptライブラリ【ScrollHintの使い方】
Javascriptのライブラリ「ScrollHint」を使えば、下の例のようなスクロール可能を示すアイコンを簡単に表示することができます。...【もっと読む】
