htmlcsshtml-tablescrollbarfixed-header-tables

<table> with fixed <thead> and scrollable <tbody>


I've looked through questions here and articles all over the internet, but haven't found yet solution that would satisfy my requirements. So now in 2017, is there an elegant way to have a <table> that would:

  1. be written in html+css (no js)
  2. have fixed header (not scrollable; not sticky)
  3. have scrollable <tbody> (scrollbar may be always visible)
  4. header and body would handle resizing properly and not mess alignment of the <thead> columns and the <tbody> columns
  5. would not use nested tables or separate table for header

Solution

  • This solution fulfills all 5 requirements:

    table {
      width: 100%;
    }
    
    table, td {
      border-collapse: collapse;
      border: 1px solid #000;
    }
    
    thead {
      display: table; /* to take the same width as tr */
      width: calc(100% - 17px); /* - 17px because of the scrollbar width */
    }
    
    tbody {
      display: block; /* to enable vertical scrolling */
      max-height: 200px; /* e.g. */
      overflow-y: scroll; /* keeps the scrollbar even if it doesn't need it; display purpose */
    }
    
    th, td {
      width: 33.33%; /* to enable "word-break: break-all" */
      padding: 5px;
      word-break: break-all; /* 4. */
    }
    
    tr {
      display: table; /* display purpose; th's border */
      width: 100%;
      box-sizing: border-box; /* because of the border (Chrome needs this line, but not FF) */
    }
    
    td {
      text-align: center;
      border-bottom: none;
      border-left: none;
    }
    <table> 
      <thead> 
        <tr>
          <th>Table Header 1</th>
          <th>Table Header 2</th>
          <th>Table Header 3</th>
        </tr> 
      </thead>
      <tbody>
        <tr>
          <td>Data1111111111111111111111111</td>
          <td>Data</td>
          <td>Data</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data2222222222222222222222222</td>
          <td>Data</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data</td>
          <td>Data3333333333333333333333333</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data</td>
          <td>Data</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data</td>
          <td>Data</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data</td>
          <td>Data</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data</td>
          <td>Data</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data</td>
          <td>Data</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data</td>
          <td>Data</td>
        </tr>
        <tr>
          <td>Data</td>
          <td>Data</td>
          <td>Data</td>
        </tr>
      </tbody>
    </table>