Search code examples
javascripthtmlcssreactjscss-tables

Table with horizontal and vertical scroll with fixed header


I do have a table with horizontal and vertical scroll with a fixed header with elements taking as much as space it needs. I am working with React. It would be awesome if there is a react based solution too if CSS alone cannot solve it.

Note:

  • I did try other solutions here but it is not what I'm looking for
  • It would be better if td can have min-width set on them too
  • The header shows menu when it is clicked for sorting and filtering

Solution

  • There's a simple CSS solution to fix rows(headers) and columns in a table.

    th {
      position: sticky:
      top: 0;
    }
    

    The above snippet will fix the header to the top. Then it's just a matter of adding a simple overflow to the parent container of the table. You can find a simple example below -

    .table-container {
      overflow: auto;
      max-height: 160px;
      border: 1px solid red;
    }
    
    th {
      position: sticky;
      top: 0;
      background: white;
    }
    <div class="table-container">
      <table>
        <thead>
          <tr>
            <th>Head 1</th>
            <th>Head 2</th>
            <th>Head 3</th>
            <th>Head 4</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
          <tr>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
            <td>Data</td>
          </tr>
        </tbody>
      </table>
    </div>