tableタグを使って表を組む事がありますが、スマホなどのレスポンシブ対応で横スクロールさせたりする際に、見出しもスクロールされて見難くなります。そんな時に役に立つのがposition: sticky;を使った行や列を固定スクロールする方法です。
今回はテーブルの列や行をposition: sticky;で固定してスクロールする方法を解説していきます。
position: sticky;とは
position: sticky;とはpositionプロパティの値の1つで、親要素を基準に、スクロール時に指定した位置まで要素がきた場合、その位置で固定できるものになります。
詳しくは、position: sticky;の使い方や効かない場合の対処法について【CSS】で解説していますのでご覧ください。
行(横)を固定してスクロールする
行(横)を固定してスクロールする方法です。
以下のコードをご覧ください。
<table>
<tbody>
<tr>
<th class="sticky">見出し</th>
<th class="sticky">見出し</th>
<th class="sticky">見出し</th>
</tr>
<tr>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
</tbody>
</table>
table {
width: 100%;
}
td,th {
padding: 25px 20px;
border: 1px solid #E4E4E4;
border-collapse: collapse;
}
th {
color: #FFF;
background-color: #202124;
}
.sticky {
position: sticky;
top: 0;
}
.sticky::before {
content: "";
width: 100%;
height: 100%;
display: block;
border: 1px solid #E4E4E4;
position: absolute;
top: -1px;
left: -1px;
box-sizing: content-box;
}
見出し | 見出し | 見出し |
---|---|---|
内容 | 内容 | 内容 |
内容 | 内容 | 内容 |
内容 | 内容 | 内容 |
内容 | 内容 | 内容 |
内容 | 内容 | 内容 |
上記例では、一番上の行(横)を固定するためにposition: sticky;を指定し、親要素を基準に上で固定する為にtop: 0;を指定しています。
また、position: sticky;でスクロールさせた際に、親要素のborderも一緒にスクロールされてチラついて見える為、疑似要素::beforeを被せています。
※リセットCSS等で疑似要素にbox-sizing: border-box;が指定されている場合はcontent-boxを指定するか、widthやheightの値をcalc(100% + 2px)にしてください。
列(縦)を固定してスクロールする
続いて、列(縦)を固定してスクロールする方法です。
以下のコードをご覧ください。
<table>
<tbody>
<tr>
<th class="sticky">見出し</th>
<td>内容</td>
<td>内容</td>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<th class="sticky">見出し</th>
<td>内容</td>
<td>内容</td>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<th class="sticky">見出し</th>
<td>内容</td>
<td>内容</td>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
</tbody>
</table>
table {
width: 150%;
}
td,th {
padding: 25px 20px;
border: 1px solid #E4E4E4;
}
th {
color: #FFF;
background-color: #202124;
}
.sticky {
position: sticky;
left: 0;
}
.sticky::before {
content: "";
width: 100%;
height: 100%;
display: block;
border: 1px solid #E4E4E4;
position: absolute;
top: -1px;
left: -1px;
box-sizing: content-box;
}
見出し | 内容 | 内容 | 内容 | 内容 | 内容 |
---|---|---|---|---|---|
見出し | 内容 | 内容 | 内容 | 内容 | 内容 |
見出し | 内容 | 内容 | 内容 | 内容 | 内容 |
上記例では、一番左の列(縦)を固定するためにposition: sticky;を指定し、親要素を基準に上で固定する為にleft: 0;を指定しています。
行(横)の固定と同じく、position: sticky;でスクロールさせた際に、親要素のborderも一緒にスクロールされてチラついて見える為、疑似要素::beforeを被せています。
※リセットCSS等で疑似要素にbox-sizing: border-box;が指定されている場合はcontent-boxを指定するか、widthやheightの値をcalc(100% + 2px)にしてください。
行(横)と列(縦)の両方を固定してスクロールする
最後に、行(横)と列(縦)の両方を固定してスクロールする方法です。
以下のコードをご覧ください。
<table>
<tbody>
<tr>
<th class="sticky corner">見出し</th>
<th class="sticky">見出し</th>
<th class="sticky">見出し</th>
<th class="sticky">見出し</th>
</tr>
<tr>
<th class="sticky">見出し</th>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<th class="sticky">見出し</th>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<th class="sticky">見出し</th>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<th class="sticky">見出し</th>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
<tr>
<th class="sticky">見出し</th>
<td>内容</td>
<td>内容</td>
<td>内容</td>
</tr>
</tbody>
</table>
table {
width: 150%;
}
td,th {
padding: 25px 20px;
border: 1px solid #E4E4E4;
}
th {
color: #FFF;
background-color: #202124;
}
.sticky {
position: sticky;
top: 0;
left: 0;
z-index: 1;
}
.sticky.corner {
z-index: 2;
}
.sticky::before {
content: "";
width: 100%;
height: 100%;
display: block;
border: 1px solid #E4E4E4;
position: absolute;
top: -1px;
left: -1px;
box-sizing: content-box;
}
見出し | 見出し | 見出し | 見出し |
---|---|---|---|
見出し | 内容 | 内容 | 内容 |
見出し | 内容 | 内容 | 内容 |
見出し | 内容 | 内容 | 内容 |
見出し | 内容 | 内容 | 内容 |
見出し | 内容 | 内容 | 内容 |
上記例では、一番上と左の固定するセルにposition: sticky;を指定し、親要素を基準に左上に固定する為にtop: 0;とleft: 0;を指定しています。
その他に、一番左上のセルのみ縦横スクロール時に隠れないようにz-indexプロパティの値を他より高く指定しています。
行(横)や列(縦)の固定と同じく、position: sticky;でスクロールさせた際に、親要素のborderも一緒にスクロールされてチラついて見える為、疑似要素::beforeを被せています。
※リセットCSS等で疑似要素にbox-sizing: border-box;が指定されている場合はcontent-boxを指定するか、widthやheightの値をcalc(100% + 2px)にしてください。
さいごに
いかがでしたでしょうか。
今回は、テーブルの列や行をposition: sticky;で固定してスクロールする方法を解説しました。
テーブルの見出し部分を固定する事で見やすくなりますので、レスポンシブ対応時やテーブルが長くなってしまう際に使用してみてください。