On a hybrid web page, one section includes a scrollable table of names with some information about them. Ideally, this table would have fixed headings with scrollable rows below. But I cannot seem to get this to work correctly.
The glaring problem here, is that (at least on Chrome latest) the row data is merged with (does not overwrite) the headings so that both values occupy the same space, making either difficult to read. One other problem is the headings move (only by a few pixels, but they do move) as the table is scrolled. While we can live with the latter, it seems unprofessional and not ideal.
I have tried inserting thead ... /thead tbody ... /tbody tags in the appropriate places... the result is that the alignment of colums no longer matches between header and body.
I've found some thirty!! answers to this sort of problem at this question. If I remove the top:0 specification from the th atttributes, the heading scrolls with the body. Same with position:sticky.
If I remove 'overflow:auto' from the tbody, as seems to be suggested in the above post, I lose the ability to scroll and the table grows beyond the desired window.
Some of the "working solutions" in that post include JavaScript, and we'd prefer to avoid that complexity if possible. Others don't really describe what they're doing so it becomes difficult to follow.
What am I doing wrong to cause this table to act in such a way?
.fixed_header_watchers tbody {
display: block;
overflow: auto;
height: 300px;
width: 100%;
}
.fixed_header_watchers th {
top: 0;
position: sticky;
padding: 0 0px;
border-collapse: collapse;
font-size: 100%;
border: none;
white-space: nowrap;
padding-left: 5px;
}
* {
padding: 0;
margin: 0;
}
<div id='watchers'>
<table class='fixed_header_watchers'>
<tr>
<th colspan=2>Watcher</th>
<th>Joined</th>
<th>Latest</th>
</tr>
<tr>
<td style='text-align:right;'>40</td>
<td>Wrestler<br>@wrestler</td>
<td>08:18</td>
<td style='text-align:right;'>0.3m</td>
</tr>
<tr>
<td style='text-align:right;'>39</td>
<td>Allen Evans - AME Arts</td>
<td>08:16</td>
<td style='text-align:right;'>0.0m</td>
</tr>
<tr>
<td style='text-align:right;'>38</td>
<td>Ct Pirate<br>@Missing</td>
<td>08:13</td>
<td style='text-align:right;'>0.0m</td>
</tr>
<tr>
<td style='text-align:right;'>37</td>
<td>Will</td>
<td>08:12</td>
<td style='text-align:right;'>0.0m</td>
</tr>
<tr>
<td style='text-align:right;'>36</td>
<td>Derth Of 13<br>Sep 11 22, 56.0 weeks</td>
<td>08:11</td>
<td style='text-align:right;'>5.9m</td>
</tr>
<tr>
<td style='text-align:right;'>35</td>
<td>Joy Robbins<br>@joyorobbins6838</td>
<td>08:11</td>
<td style='text-align:right;'>6.7m</td>
</tr>
<tr>
<td style='text-align:right;'>34</td>
<td>Spanky<br>@spanky</td>
<td>08:07</td>
<td style='text-align:right;'>11.2m</td>
</tr>
<tr>
<td style='text-align:right;'>33</td>
<td>Bob Crawford Art<br>Sep 24 23, 2.0 weeks</td>
<td>08:04</td>
<td style='text-align:right;'>0.0m</td>
</tr>
<tr>
<td style='text-align:right;'>32</td>
<td>(Barkley)107 Drifters</td>
<td>08:03</td>
<td style='text-align:right;'>0.0m</td>
</tr>
</table>
This is a slight bit of overkill just to illustrate.
Here I use a grid layout - tables are kind of a grid after all.
I added some ugly borders just to show what is where - they can be removed.
Basically I define a super-centered body and #watchers.
display: grid; place-items: center;Then I start defining grids within grids so we can customize things and size them. Note how I gave the header and body the same column widths
grid-template-columns: 2em 20ch 8ch 6ch;but place the first header within the first two columns. withfirstname, primarily just for clarity of use; that definition could be combined in one CSS block also.I arbitrarily assigned the
tbodyaheight: 10em;just for this example.A good bit of this is just some sizing like
3emfor the body row height, things like that.Side note not a fan of
<br>and those two text segments might be in spans to make styling work using a more flexible set of CSS - for example give them a different layout depending upon the view size etc.