In the snippet below, the HTML and CSS part are resolving the scrollability of tbody
, whereas, for the purpose of filling the gap between the upper content and the lower and of the screen, I applied Javascript.
function adjustTable() {
let foo = document.getElementById('foo');
let fooBody = foo.querySelector('tbody');
fooBody.style.height = 0.9 * (window.innerHeight - fooBody.getBoundingClientRect().top) + "px";
}
window.addEventListener('load', adjustTable);
window.addEventListener('resize', adjustTable);
thead, tbody {
display: block;
}
tbody {
overflow-y: auto;
}
<div>
top content
</div>
<table id="foo">
<thead>
<tr><th>... first header row</th></tr>
<tr><th>... second header row</th></tr>
</thead>
<tbody>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr><td>4</td></tr>
<tr><td>5</td></tr>
<tr><td>6</td></tr>
<tr><td>7</td></tr>
<tr><td>8</td></tr>
<tr><td>9</td></tr>
<tr><td>10</td></tr>
<tr><td>11</td></tr>
<tr><td>12</td></tr>
<tr><td>13</td></tr>
<tr><td>14</td></tr>
<tr><td>15</td></tr>
<tr><td>16</td></tr>
<tr><td>17</td></tr>
<tr><td>18</td></tr>
<tr><td>19</td></tr>
<tr><td>20</td></tr>
<tr><td>21</td></tr>
<tr><td>22</td></tr>
<tr><td>23</td></tr>
<tr><td>24</td></tr>
<tr><td>25</td></tr>
<tr><td>26</td></tr>
<tr><td>27</td></tr>
<tr><td>28</td></tr>
<tr><td>29</td></tr>
</tbody>
</table>
EDIT
As per the comment section, I was asked to edit this answer and add an adjustment for window resize as well as upper content change. I have updated the snippet above to handle resize event as well accordingly. As about handling upper content changes, a mutation observer can be used for that purpose in worst case scenarios, but if you have additional information about the upper content, then you can add handlers for it.
If we are to go with a mutation observer, then we can just call adjustTable()
when dom changes are detected.