以前の応用。
前の記事
やっていく
先頭行と先頭列を見出し(th)にする。
<div class="table_wrap">
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<th></th>
<td></td>
<td></td>
<td></td>
</tr>
︙
</tbody>
</table>
</div>
こう。
.table_wrap{
width: 100%;
max-width: 1200px;
border-radius: 12px;
border: 1px solid #ddd;
overflow-x: auto;
}
.table_wrap table{
width: 100%;
border-collapse: collapse;
}
.table_wrap table :is(th,td){
border: 1px solid #ddd;
white-space: nowrap;
}
.table_wrap table thead th,
.table_wrap table tbody th:first-child{
position: sticky;
top: 0;
left: 0;
background: #fff;
z-index: 1;
}
.table_wrap table thead th::before,
.table_wrap table tbody th:first-child::before{
content: "";
width: 100%;
height: 100%;
display: block;
position: absolute;
top: -1px;
left: -1px;
border: 1px solid #ddd;
}
.table_wrap table thead th:first-child{ z-index: 2;}
.table_wrap table tbody tr:last-child th:first-child::before{
border-bottom: none;
}
.table_wrap table :is(th,td):first-child{ border-left: none;}
.table_wrap table :is(th,td):last-child{ border-right: none;}
.table_wrap table :is(thead,tbody):first-child tr:first-child :is(th,td){ border-top: none;}
.table_wrap table :is(tbody,tfoot):last-child tr:last-child :is(th,td){ border-bottom: none;}
tableをスクロール可能にするのは前述の記事を参照。
今回の固定について、コードだとめちゃめちゃ長いので要点で言えば、thの位置固定はposition:sticky;で可能になる。
要素がレイヤー化されるんで、スクロールした時に上に来るようにz-indexを付与。左右上下のスクロールで一番左上、エクセルでいうA1の位置にあるthを最前面に設定する。そうしないとなんかキモいことになる。
thの背景や枠線が無くなるので::beforeでカバーする必要がある。最下段のthの::beforeが1pxはみ出す。これは枠線のせいで、そもそもtableをスクロール可能にする際にtable外枠はtableのラッピング(.table_wrap)で付与してるので削る。
なお、rowspanで結合させてもスクロールに対応するんだけど、文字の位置が固定されてなんかちょっと変な感じになる。
これをいちいち手打ちするのはだるいから、専用のclassを作ってパッケージ化してしまうのがいいですね。
コメント