Making table rows clickable
Note: some content on this page has had
aria-hidden="true"
added for more precise testing.
Our example table
For clarity, we'll use a short table of invoices. The Reference column contains a unique identifier for each row.
In situations where we don't have a unique identifier for each row, it might be worth asking if we there should be one. Is it clear what each row is referring to?
Reference |
To |
Description |
Amount |
INV-004 |
Scarlett Papava |
Plane ticket |
1,000 |
INV-008 |
Alec Trevelyan |
Statue with two faces |
500 |
Make it clickable!
Here are some things to consider for best usability and accessibility.
- Link affordance: the link looks like a link.
- Link text: the link text describes the link destination.
- Table semantics: the table keeps all its semantics.
- Keyboard interactions: only interactive elements receive focus.
- Pointer interactions: links can be opened in a new tab. (Note that buttons can not).
Some options:
Option: make one cell contents a link to the invoice
The DOM looks like: table > tr > td > a
.
- ✔️ Link affordance: the link looks like a link.
- ✔️ Link text: the link text describes the link destination.
- ✔️ Table semantics: the table keeps all its semantics.
- ✔️ Keyboard interactions: only interactive elements receive focus.
- ✔️ Pointer interactions: links can be opened in a new tab.
Reference |
To |
Description |
Amount |
INV-004 |
Scarlett Papava |
Plane ticket |
1,000 |
INV-008 |
Alec Trevelyan |
Statue with two faces |
500 |
Option: make every cell's contents a link to the invoice
The DOM looks like: table > tr > td > a
.
- ✔️ Link affordance: the links look like links.
- 🚫 Link text: the link text does not describes the link destination for each link.
- ✔️ Table semantics: the table keeps all its semantics.
- ✔️ Keyboard interactions: only interactive elements receive focus.
- ✔️ Pointer interactions: links can be opened in a new tab.
Option: wrap each row in a link
The DOM looks like: table > a > tr > td
. This is invalid HTML, so it causes errors.
- 🚫 Link affordance: the links are rendered empty, outside the table.
- 🚫 Link text: the link text is empty.
- ✔️ Table semantics: the table keeps all its semantics.
- 🚫 Keyboard interactions: the links still receive focus, but they're empty.
- 🚫 Pointer interactions: the links have no visible target.
Option: wrap each row of cells in a link
The DOM looks like: table > tr > a > td
. This is invalid HTML, so it causes errors.
- 🚫 Link affordance: the links are rendered empty, outside the table.
- 🚫 Link text: the link text is empty.
- ✔️ Table semantics: the table keeps all its semantics.
- 🚫 Keyboard interactions: the links still receive focus, but they're empty.
- 🚫 Pointer interactions: the links have no visible target.
Reference |
To |
Description |
Amount |
INV-004 |
Scarlett Papava |
Plane ticket |
1,000 |
INV-008 |
Alec Trevelyan |
Statue with two faces |
500 |
Option: give each row a role of link
For this option, we need to add keyboard interactivity to each row, add JavaScript to handle the click events, and add hover styles.
- 🚫 Link affordance: users have to hover or tab to the link to find it. The rows-as-link don't look like links.
- 🥴 Link text: the link text is the text of all the cells in the row. It's a bit too long, and not very clear.
- 🚫 Table semantics: the table semantics are broken. The rows have been replaced by links.
- 🥴 Keyboard interactions: only interactive elements receive focus. But... table rows aren't usually interactive, so this is confusing.
- 🚫 Pointer interactions: links can't be opened in a new tab. Only
a
elements with an [href]
can be opened in a new tab.
Reference |
To |
Description |
Amount |
INV-004 |
Scarlett Papava |
Plane ticket |
1,000 |
INV-008 |
Alec Trevelyan |
Statue with two faces |
500 |