Tables on a phone: scroll, cards or fewer columns

Three ways to fit a table on a phone and how to choose, main columns first, numbers that can be compared and plans one per screen — with live examples.

Interface elements Updated

In short

A table does not fit a phone screen, and shrinking it until it fits makes it unreadable. The way out depends on how the data is read. Values that are compared down a column — prices, specifications — stay a table that scrolls sideways inside its own box, with the first column fixed and a shadow at the edge that shows there is more. Rows that are read one at a time — orders, applications, documents — become cards. Plans are shown one per screen with a switcher. Reports with many columns keep the main three, and the rest open with a button. Numbers are aligned to the right with digits of equal width and the unit in the header, and in the code the table stays a real table.

Three ways to fit a table on a phone

The same price list. The middle table really scrolls — swipe it sideways: the first column stays in place.

Squeezed

tiny text, words broken

Scroll, first column fixed

for comparing: swipe sideways

Cards

for a list: one row — one card

Which way for which data

The question is the same every time: are the values compared with each other or is each row read on its own?

DataWayWhy
Price lists, specifications scroll, first column fixed values are compared down the column
Orders, applications, documents cards each row is read on its own
Plans and tariffs one per screen with a switcher a plan is chosen, not read cell by cell
Reports with many columns main columns + “All columns” most people need three columns out of ten
Timetables a list by day on a phone one day is viewed at a time

Main columns first

An order list for a manager. On a narrow screen — the number, the total and the status; the rest is one tap away.

Numbers that can be compared

Right edge, digits of equal width, one format and the unit in the header — and the column reads like a scale.

Mixed
Right-aligned, unit in the header

When numbers are aligned to the right, thousands stand under thousands, and the largest value is seen without reading. Dates, codes and phone numbers are not compared by size — they stay on the left. A number never breaks across lines: digit groups are joined with non-breaking spaces.

Plans: one per screen

A comparison table of three plans is the most common table that breaks on a phone.

Photo cloud

Press a plan in the switcher. A three-column table on a phone turns into small text and sideways scrolling; one plan per screen is read in full, and comparing is done by switching.

Tables in code: 3 examples

Markup that keyboards and screen readers understand, a table that scrolls with a fixed column, and a list that turns into cards.

Markup

The box can be scrolled from the keyboard; the caption and headers tell screen readers what is in each cell.

table.html
<div class="table-wrap" role="region" aria-labelledby="worktops-caption" tabindex="0">
  <table class="table">
    <caption id="worktops-caption">Worktops: price and lead time</caption>
    <thead>
      <tr>
        <th scope="col">Material</th>
        <th scope="col">Thickness</th>
        <th scope="col" class="num">Price per m², $</th>
        <th scope="col">Lead time</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th scope="row">Oak</th>
        <td>40 mm</td>
        <td class="num">240</td>
        <td>14 days</td>
      </tr>
    </tbody>
  </table>
</div>

Scroll with a fixed column

Shadows at the edges appear only while there is more to scroll — no script needed.

table.css
/* The table scrolls inside its own box, not the whole page */
.table-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* Edge shadows: the covers move with the content, the shadows stay */
  background:
    linear-gradient(to right, var(--color-surface) 30%, transparent) left / 2rem 100% no-repeat local,
    linear-gradient(to left, var(--color-surface) 30%, transparent) right / 2rem 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgb(0 0 0 / 0.15), transparent) left / 0.75rem 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgb(0 0 0 / 0.15), transparent) right / 0.75rem 100% no-repeat scroll;
}

.table {
  border-collapse: collapse;
  white-space: nowrap;
}

/* The first column stays in place */
.table tr > :first-child {
  position: sticky;
  left: 0;
  background: var(--color-surface);
}

/* Numbers: right edge, digits of equal width */
.table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

Rows into cards

The column name comes from data-label. Some browsers stop announcing a table whose display was changed — role="table", "row" and "cell" in the markup bring it back.

orders.css
/* A list of orders: on a phone every row becomes a card */
@media (max-width: 47.99rem) {
  .table--cards thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .table--cards tr {
    display: grid;
    gap: var(--space-1);
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--color-border);
  }

  /* <td data-label="Total">1,120</td> */
  .table--cards td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
  }

  .table--cards td::before {
    content: attr(data-label);
    color: var(--color-text-muted);
  }
}

7 rules for tables on a phone

  1. 01

    Do not shrink to fit

    Text in cells is at least 14 px, even if the table has to scroll.

  2. 02

    The way follows the reading

    Compared down a column — scroll; read row by row — cards.

  3. 03

    The first column stays

    While scrolling sideways it is always clear which row you are in.

  4. 04

    Show that there is more

    A shadow or a cut column at the edge.

  5. 05

    Numbers on the right, the unit in the header

    Digits of equal width and one format in the whole column.

  6. 06

    Fewer columns on a phone

    The main ones in view, the rest by a button.

  7. 07

    A table stays a table

    In the code — table, th and caption, whatever it looks like.

Common mistakes with tables on a phone

  1. Text shrunk to 9 px

    Nothing is readable without zooming in.

  2. Sideways scroll without a hint

    People do not know that half the columns are off screen.

  3. Cards for comparing

    To compare prices you have to scroll up and down and remember.

  4. Units in every cell, in different formats

    “240 USD”, “$210.00” and “320$” in one column.

  5. A number broken across lines

    “24” on one line and “000” on the next.

  6. A table made of divs

    Screen readers cannot move along rows and columns, and search engines do not see the data.

Questions about tables on a phone

Sideways scroll or cards?

Scroll when values are compared down a column, cards when each row is read on its own.

How do I show that a table scrolls?

A shadow at the edge and a column cut in half. Both are done with CSS, without a script.

Which columns can be hidden on a phone?

Those that are not needed for the first decision. Ask the people who use the table which three columns they look at.

Should all numbers be right-aligned?

Amounts, prices and quantities — yes. Dates, codes and phone numbers are not compared by size and stay on the left.

Zebra stripes or lines?

Thin lines are enough for short tables; stripes help the eye in long, wide rows.

Can a table be published as an image?

Better not: it cannot be read on a phone without zooming, found by search or read by a screen reader.

Online form

Data that reads
on a phone

I design and build tables, price lists and dashboards that work on a phone as well as on a big screen. Tell me about the project — I answer within one working day.

Or write to [email protected]