w3docs logo
  1. Snippets
  2. HTML
  3. How to Create a Table with a Fixed Header and Scrollable Body

How to Create a Table with a Fixed Header and Scrollable Body

Solutions with CSS properties

In this tutorial, find some methods of creating an HTML table, which has a fixed header and scrollable body. Of course, you need to use CSS.

It is possible to achieve such a result by setting the position property to “sticky” and specifying 0 as a value of the top property for the <th> element.

Example of creating a table with a scrollable body by using the position property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .tableFixHead {
        overflow-y: auto;
        height: 106px;
      }
      .tableFixHead thead th {
        position: sticky;
        top: 0;
      }
      table {
        border-collapse: collapse;
        width: 100%;
      }
      th,
      td {
        padding: 8px 16px;
        border: 1px solid #ccc;
      }
      th {
        background: #eee;
      }
    </style>
  </head>
  <body>
    <div class="tableFixHead">
      <table>
        <thead>
          <tr>
            <th>Col 1</th>
            <th>Col 2</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1.1</td>
            <td>2.1</td>
          </tr>
          <tr>
            <td>1.2</td>
            <td>2.2</td>
          </tr>
          <tr>
            <td>1.3</td>
            <td>2.3</td>
          </tr>
          <tr>
            <td>1.4</td>
            <td>2.4</td>
          </tr>
          <tr>
            <td>1.5</td>
            <td>2.5</td>
          </tr>
        </tbody>
      </table>
    </div>
  </body>
</html>

Result

Col 1 Col 2
1.1 2.1
1.2 2.2
1.3 2.3
1.4 2.4
1.5 2.5

Let’s see another method of creating a table with a fixed header and scrollable body. In the example below, we set the display to “block” for the <tbody> element so that it’s possible to apply the height and overflow properties.

Example of creating a table with a scrollable body by using the display property:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .fixed_header {
        width: 400px;
        table-layout: fixed;
        border-collapse: collapse;
      }
      .fixed_header tbody {
        display: block;
        width: 100%;
        overflow: auto;
        height: 100px;
      }
      .fixed_header thead tr {
        display: block;
      }
      .fixed_header thead {
        background: black;
        color: #fff;
      }
      .fixed_header th,
      .fixed_header td {
        padding: 5px;
        text-align: left;
        width: 200px;
      }
    </style>
  </head>
  <body>
    <table class="fixed_header">
      <thead>
        <tr>
          <th>Col 1</th>
          <th>Col 2</th>
          <th>Col 3</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
        </tr>
        <tr>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
        </tr>
        <tr>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
        </tr>
        <tr>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
        </tr>
        <tr>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
          <td>Text</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>

As you have noticed, in the previous examples, we didn’t use borders. However, if you need to add borders, you can set them with the box-shadow property.

Example of creating a table with a scrollable body:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .tableFixHead {
        overflow-y: auto;
        height: 100px;
      }
      .tableFixHead thead th {
        position: sticky;
        top: 0;
      }
      table {
        border-collapse: collapse;
        width: 100%;
      }
      th,
      td {
        padding: 8px 16px;
      }
      th {
        background: #eee;
      }
      .tableFixHead,
      .tableFixHead td {
        box-shadow: inset 1px -1px #000;
      }
      .tableFixHead th {
        box-shadow: inset 1px 1px #000, 0 1px #000;
      }
    </style>
  </head>
  <body>
    <div class="tableFixHead">
      <table>
        <thead>
          <tr>
            <th>Col 1</th>
            <th>Col 2</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1.1</td>
            <td>2.1</td>
          </tr>
          <tr>
            <td>1.2</td>
            <td>2.2</td>
          </tr>
          <tr>
            <td>1.3</td>
            <td>2.3</td>
          </tr>
          <tr>
            <td>1.4</td>
            <td>2.4</td>
          </tr>
          <tr>
            <td>1.5</td>
            <td>2.5</td>
          </tr>
        </tbody>
      </table>
    </div>
  </body>
</html>
Do you find this helpful?