Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to make a table responsive with scrolling

Short answer

Wrap the table in a block with overflow-x: auto — on a narrow screen horizontal scrolling appears inside the block rather than on the whole page:

<style>
  .table-wrap { overflow-x: auto; max-width: 300px; border: 1px solid silver; }
  table { border-collapse: collapse; }
  th, td { padding: 6px 12px; white-space: nowrap; text-align: left; }
</style>
 
<div class="table-wrap" tabindex="0" role="region" aria-label="Price list">
  <table>
    <tr><th>Plan</th><th>Storage</th><th>Users</th><th>Support</th><th>Price</th></tr>
    <tr><td>Basic</td><td>10 GB</td><td>1</td><td>Email</td><td>$5</td></tr>
    <tr><td>Team</td><td>100 GB</td><td>10</td><td>Chat</td><td>$25</td></tr>
  </table>
</div>

white-space: nowrap keeps the cells from shrinking into narrow columns with one word per line.

Scrolling from the keyboard

The tabindex="0" attribute lets the wrapper be selected with Tab and scrolled with the arrows. Together with it, role="region" and aria-label are set so a screen reader explains what the area is.

Other options

On a phone a table can be rebuilt into cards: a media query turns rows into blocks, and the headings are shown next to the values. That is harder, and scrolling fits most cases.

Common mistake

overflow-x: auto is put on the table itself. This property does not work on a <table> element: the table still stretches past the screen, and the whole page scrolls. A wrapper is needed — a plain <div>.

Functions used in this recipe

  • overflow — What to do with content that does not fit into the element.
  • <table> — A table made of rows (`<tr>`) and cells.
  • white-space — How spaces and line breaks in the source are handled and whether lines may wrap.
  • tabindex — Controls whether an element can be reached with the Tab key.

Thanks for reading!

Donate to the site — we work hard for you.