· table · 2 min read

Fixed HTML table header

Celebrate the readability prowess inherent within the expansive table

Celebrate the readability prowess inherent within the expansive table

Solution

  1. Enclose your table within a container, thereafter establishing a max-width to facilitate fixed row headers, or alternatively, setting a max-height to accommodate fixed vertical columns within the table container.
  2. Elevate your fixed cells to a sticky position, augmenting their z-index layer, and ensuring their adherence to the container through the implementation of sticky points.

Row header

.container {
  max-height: 256px;
}

.header-cell {
  position: sticky;
  top: 0;
  z-index: 10;
}
TitleTitle
ContentContent
ContentContent
ContentContent
ContentContent
ContentContent

Column header

.container {
  max-width: 768px;
}

.header-cell {
  position: sticky;
  left: 0;
  z-index: 10;
}
TitleContentContentContentContent
TitleContentContentContentContent
TitleContentContentContentContent
TitleContentContentContentContent
TitleContentContentContentContent
TitleContentContentContentContent

Bi-direction header

.container {
  max-height: 256px;
  max-width: 768px;
}

.row-header-cell {
  position: sticky;
  top: 0;
  z-index: 10;
}

.column-header-cell {
  position: sticky;
  left: 0;
  z-index: 20;
}

.corner-header-cell {
  position: sticky;
  left: 0;
  top: 0;
  z-index: 30;
}
TitleTitleTitleTitle
TitleContentContentContentContent
TitleContentContentContentContent
TitleContentContentContentContent
TitleContentContentContentContent
TitleContentContentContentContent

Example code

These elements are styled using class names from the Tailwind framework.

Fixed row header

<div class="max-h-56 overflow-auto">
  <table class="text-center border-collaps">
    <thead>
      <tr>
        <th class="min-w-64 sticky top-0 z-10 bg-gray-100 dark:bg-gray-800 p-3">Title</th>
        <th class="min-w-64 sticky top-0 z-10 bg-gray-100 dark:bg-gray-800 p-3">Title</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <td>Content</td>
        <td>Content</td>
      </tr>
    </tbody>
  </table>
</div>

Fixed column header

<div class="max-w-3xl overflow-auto">
  <table class="text-center border-collaps">
    <thead>
      <tr>
        <th class="min-w-64 sticky left-0 z-10 bg-gray-100 dark:bg-gray-800 p-3">Title</th>
        <td class="min-w-64 font-normal">Content</td>
        <td class="min-w-64 font-normal">Content</td>
        <td class="min-w-64 font-normal">Content</td>
        <td class="min-w-64 font-normal">Content</td>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th class="sticky left-0 z-10 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <th class="sticky left-0 z-10 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <th class="sticky left-0 z-10 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <th class="sticky left-0 z-10 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <th class="sticky left-0 z-10 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
    </tbody>
  </table>
</div>

Fixed bi-direction header

<div class="max-w-3xl max-h-56 overflow-auto">
  <table class="text-center border-collaps">
    <thead>
      <tr>
        <th class="min-w-64 sticky left-0 top-0 z-30 bg-gray-100 dark:bg-gray-800 p-3" />
        <th class="min-w-64 sticky top-0 z-10 bg-gray-100 dark:bg-gray-800 p-3">Title</th>
        <th class="min-w-64 sticky top-0 z-10 bg-gray-100 dark:bg-gray-800 p-3">Title</th>
        <th class="min-w-64 sticky top-0 z-10 bg-gray-100 dark:bg-gray-800 p-3">Title</th>
        <th class="min-w-64 sticky top-0 z-10 bg-gray-100 dark:bg-gray-800 p-3">Title</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th class="sticky left-0 z-20 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <th class="sticky left-0 z-20 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <th class="sticky left-0 z-20 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <th class="sticky left-0 z-20 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
      <tr>
        <th class="sticky left-0 z-20 bg-gray-100 dark:bg-gray-800">Title</th>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
        <td>Content</td>
      </tr>
    </tbody>
  </table>
</div>
Back to Blog