You may use instead a wrapper and position:sticky
, this way the table-layout algorythm works for the whole table and every columns and rows remain perfectly aligned.
Classic usage in the snippet below :
.myTableWrapper {
width:min-content;/* wraps onto table's width */
height: 100px;
overflow-y:auto;
padding-right:1.3em;
}
thead {
background:white;
position:sticky;
top:0;
}
<div class="myTableWrapper">
<table>
<thead>
<tr><th>TH</th><th>TH</th><th>TH</th><th>TH</th><th>TH</th></tr></thead>
<tbody>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
<tr><td>td</td><td>td</td><td>td</td><td>td</td><td>td</td></tr>
</tbody>
</table>
</div>
or you can play with display:grid
and display:content
s to avoid a wrapper and switvh from a table-layou to a grd model .
resizeable live example with sticky headers => https://codepen.io/gc-nomade/pen/abboqbR , but display:contents
is not understood yet everywhere .