<header>
  <h1>CSS responsive table</h1>
  <p>...with fixed column and row headers and scroll snap. - <a href="https://twitter.com/scottjehl/status/1407356545080434697">@scottjehl</a></p>
</header>
<main>
  <div role="region" aria-label="data table" tabindex="0" class="primary">
    <!-- Note: use the aria-label attribute above to describe this keyboard-focusable region appropriately, per your implementation. Alternatively, it could instead be an aria-labelledby attribute that points to a table caption's ID attribute. Thx for thoughts, @aardrian  -->
    <table>
      <thead>
        <tr>
          <th class="pin"> </th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
          <th>Col Header</th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
        <tr>
          <th>Row Header</th>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
          <td>Cell Data</td>
        </tr>
      </tbody>
    </table>
  </div>
  <aside>
    sidebar
  </aside>
</main>
<footer>
  Site footer
</footer>
body {
  font: 90%/1.4 system-ui;
  margin: 0;
  font-family: sans-serif;
}
header {
  padding: 7vh 5vw;
  border-bottom: 1px solid #ddd;
}
header h1,
header p {
  margin: 0;
}
footer {
  padding: 7vh 5vw;
  border-top: 1px solid #ddd;
}
aside {
  padding: 7vh 5vw;
}
.primary {
  overflow: auto;
  scroll-snap-type: both mandatory;
  height: 80vh;
}
@media (min-width: 40em) {
  main {
    display: flex;
  }
  aside {
    flex: 0 1 20vw;
    order: 1;
    border-right: 1px solid #ddd;
  }
  .primary {
    order: 2;
  }
}
table {
  border-collapse: collapse;
  border: 0;
}
th,
td {
  border: 1px solid #aaa;
  background-clip: padding-box;
  scroll-snap-align: start;
}
tbody tr:last-child th,
tbody tr:last-child td {
  border-bottom: 0;
}
thead {
  z-index: 1000;
  position: relative;
}
th,
td {
  padding: 0.6rem;
  min-width: 6rem;
  text-align: left;
  margin: 0;
}
thead th {
  position: sticky;
  top: 0;
  border-top: 0;
  background-clip: padding-box;
}
thead th.pin {
  left: 0;
  z-index: 1001;
  border-left: 0;
}
tbody th {
  background-clip: padding-box;
  border-left: 0;
}
tbody {
  z-index: 10;
  position: relative;
}
tbody th {
  position: sticky;
  left: 0;
}
thead th,
tbody th {
  background-color: #f8f8f8;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.