I am trying to make the of a table sticky to top of page as you scroll, however the table width should be constrained by its parent and allow to scroll in the x direction.
However as soon as the overflow-x is added, the stickyness doesn't work, and if there's no overflow, then the head sticks, but the table content breaks the bounds of its parent container.
Example Pen https://codepen.io/JamesBlack91/pen/KKRJdQK
div {
max-width: 300px;
overflow-x: auto;
}
table thead {
position: sticky;
top: 0;
}
<div>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
<th>Column 9</th>
<th>Column 10</th>
<th>Column 11</th>
<th>Column 12</th>
<th>Column 13</th>
<th>Column 14</th>
<th>Column 15</th>
<th>Column 16</th>
<th>Column 17</th>
<th>Column 18</th>
<th>Column 19</th>
<th>Column 20</th>
</tr>
</thead>
<tbody>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
</tbody>
</table>
</div>
If you scroll, the head isn't sticky, but if you comment out the overflow on the div, the head is sticky but the columns overflow the 300px max.
I have read all about thead (previously) not supporting sticky, I've also tried on the < th > to no result. I've tried putting overflow on the table/thead/tbody instead of the ancestor div, but nothing seems to work.
I really want to avoid using javascript and I'm sure there's a simple css solution I just don't know.
CodePudding user response:
<style>
.lock-header {
height:100% !important;
}
.lock-header thead th {
}
.lock-header>table {
}
.lock-header tfoot td {
}
.lock-header {
overflow-y: auto;
max-height: 300px;
width:300px;
padding:0;
}
.lock-header thead>tr:first-child>th {
background-color: rgba(240,240,240,0.8);
z-index:1;
position: sticky;
top: 0;
}
.lock-header>table {
border-collapse: collapse;
width: 100%;
}
.lock-header tfoot td {
background-color: rgba(240,240,240,1);
z-index:99;
position: sticky;
bottom: 0;
}
</style>
<div >
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
<th>Column 9</th>
<th>Column 10</th>
<th>Column 11</th>
<th>Column 12</th>
<th>Column 13</th>
<th>Column 14</th>
<th>Column 15</th>
<th>Column 16</th>
<th>Column 17</th>
<th>Column 18</th>
<th>Column 19</th>
<th>Column 20</th>
</tr>
</thead>
<tbody>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
<tr>
<td>Some fake row</td>
</tr>
</tbody>
</table>
</div>
is this what you want ? I tried it on codepen and it works
CodePudding user response:
This can't be done with just CSS. The sticky position requires the initial overflow value on parent containers, you will have to use JS to stick the header row.