When I learned HTML tables back in the 90s, at some point I discovered the <thead> element for grouping the <th> column headers. What I missed was there should be a <tr> element between the two. In other words, a well-formed HTML table with a header looks like this:
<table> <thead> <tr> <th>Name</th> <th>Value</th> <th>Date</th> </tr> </thead> <tbody> <tr> <td>USERNAME</td> <td>John.Smith</td> <td>2017-02-18T23:47</td> </tr> </tbody> </table>
<table> <thead> <th>Name</th> <th>Value</th> …
The latter form—<thead> directly enclosing <th>s—had always worked for me. Until yesterday when I ran afoul of an HTML5 validator on a remote API, which simply would not let me proceed until I wrapped my <th> cells with a <tr>.