X

Responsive Tables with Zebra Stripes and Accessible Scrolling

A responsive data table should stay readable at narrow widths and zoom levels without hiding information or breaking its row-and-column relationships. For a compact table, width: 100% may be enough. For a wider one, contain horizontal scrolling within the table instead of forcing the whole page to scroll.

The original example was a small leaderboard for HTML5 games. Its screenshot and embedded demo are retained below; the code here adds semantic table markup, keyboard access, and a narrow-screen fallback.

Screenshot of the original responsive table demo.

Start with a semantic HTML table

Use native table elements for data that has real row and column relationships. A caption names the table, column headers identify each column, and a row header identifies each record. These associations help people understand the data with screen readers and other assistive technology. See the WAI Tables Tutorial for more examples.

<p id="orders-hint">On a narrow screen, scroll horizontally to see every column.</p>
<div
  class="table-scroll"
  role="region"
  aria-labelledby="orders-caption"
  aria-describedby="orders-hint"
  tabindex="0"
>
  <table>
    <caption id="orders-caption">Weekly orders by product</caption>
    <thead>
      <tr>
        <th scope="col">Product</th>
        <th scope="col">Units</th>
        <th scope="col">Change</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th scope="row">Starter kit</th>
        <td>28</td>
        <td>+4</td>
      </tr>
      <tr>
        <th scope="row">Field guide</th>
        <td>16</td>
        <td>-2</td>
      </tr>
    </tbody>
  </table>
</div>

The named, focusable region gives keyboard users a place to scroll when the table is wider than its container. Keep the instruction visible; do not rely on color or a hidden gesture to explain that more columns are available.

Add responsive layout and zebra stripes

Let a small table use the available width, and allow the wrapper to scroll if the table's content needs more space. The overflow-x property controls horizontal overflow; avoid shrinking text or removing columns just to make a wide table fit.

.table-scroll {
  max-width: 100%;
  overflow-x: auto;
}

.table-scroll:focus-visible {
  outline: 3px solid #0b57d0;
  outline-offset: 3px;
}

table {
  width: 100%;
  border-collapse: collapse;
  color: #17212b;
}

caption {
  padding: 0.5rem 0;
  font-weight: 700;
  text-align: left;
}

th,
td {
  padding: 0.625rem 0.75rem;
  border-bottom: 1px solid #b8c2cc;
  text-align: start;
  vertical-align: top;
}

thead th {
  background: #24364b;
  color: #fff;
}

tbody tr:nth-child(even) {
  background: #edf3f1;
}

The tbody selector keeps the header styling separate from the alternating row colors. Stripe rows only as a visual aid: the text, borders, and semantic headers must still make the table understandable when background colors are unavailable.

If you are considering turning each row into a card on small screens, treat that as a separate layout and preserve the relationship between every value and its header. The CSS-Tricks responsive table example shows another pattern, but do not copy a visual transformation without checking its accessibility.

Check narrow screens, zoom, and keyboard use

Test the page at a viewport around 320 CSS pixels wide and at high zoom. The page itself should not gain a horizontal scrollbar; if the table needs more room, only its labeled region should scroll. WCAG's Reflow guidance permits two-dimensional scrolling for content that requires a two-dimensional layout, including some data tables; keep the rest of the page usable without horizontal scrolling.

Then check that:

  • You can reach the table region with the keyboard and scroll to the last column.
  • The table caption, row headers, and column headers make sense when read without the visual stripes.
  • Focus remains visible, and no column or cell content disappears at narrow widths.
  • The layout still works when users increase text size or use a high-contrast or forced-colors mode.

The original interactive demo is preserved here:

See the Pen Responsive Table with Zebra stripes by Kanishk Kunal on CodePen.

Categories: Development
Related Post