I need to make table cells (or rows) link to other pages. Currently they're using onClick to change url, but it's missing the UX of actual anchor elements, such as opening in new tab etc.

I tried replacing the entire row with an <a> and display: table-row style, and it works perfectly... except React insists that a is not a valid child of tbody and td is not a valid child of a.

Am I supposed to remake the entire table using styled divs, or what's the solution here?

Edit:

I have tried to make <a> cover every cell, but it's very hard to make that happen reliably since height: 100% does not work. Absolutely positioned links work only if the cell does not have any interactive contents. Using both at the same time (with absolutely positioned link behind the normal one) probably works but that's a lot of extra elements.

riv's user avatar

3

No, you can not. because <tr> can only contain <td> tags. what you can do is putting <a> tags inside <td> and use CSS to fill the td. your CSS style would be something like this:

.cell-link { display : block; width : 100%; height : 100%; text-decoration : none; color : inherit; }

Also i strongly suggest not using onclick on cells if SEO matters and you are not planning to implement any back-rendering. this can cause problems with crawler bots (you're page indexing process on search engines).

Mister Jojo's user avatar

Mister Jojo

23k6 gold badges28 silver badges46 bronze badges

hamed danesh's user avatar

2 Comments

height: 100% does not work unless parent element has a fixed height, and I can't predict the height of my rows. That's basically the main reason why I'm looking for a workaround. I tried absolutely positioned links too, but then they either cover the cell contents or are covered by it.

2026-02-14T19:57:08.203Z+00:00

The only other solution I can think of is using two <a> elements - one normal like you said, and another absolutely positioned behind the cell. But idk if that's better in the end.

2026-02-14T20:04:31.273Z+00:00

From what I understand of your question,
Are you looking for something like that ?

const myTable = document.querySelector('#my-table') , lnkPrefix = 'https://stackoverflow.com/' ; myTable.addEventListener('click', ({target: td_clicked}) => { if (!td_clicked.matches('td[data-lnk]')) return; // ignore them window.location.replace(`${lnkPrefix}${td_clicked.dataset.lnk}`); // window.open(`${lnkPrefix}${td_clicked.dataset.lnk}`, '_blank').focus(); }) td { border : 1px solid lightgrey; width : 10em; padding : 0 1em; } td[data-lnk] { background : lightblue; cursor : pointer; } td[data-lnk]:hover { color : red; border-color : black; } <table id="my-table"> <tr> <td data-lnk="questions/1687296/"> event delgation </td> <td> no link... </td> <td data-lnk="questions/72742668"> data attribute styling </td> </tr> <tr> <td> xxx </td> <td data-lnk="help/how-to-ask" > how to ask... </td> <td> yyy </td> </tr> </table>

Mister Jojo's user avatar

"I have tried to make <a> cover every cell". Something like this?

table { height:fit-content; } tr, a { height:100%; } td { border:1px solid black; } a { display:block; } a:hover { background-color:#7ff; } <table> <tr> <td><a href=#1>r1c1</a></td> <td><a href=#2>row 1 column 2</a></td> <td><a href=#3>r1<br/>c3<br/></a></td> </tr> <tr> <td><a href=#4>row 2 column 1</a></td> <td><a href=#5>r2<br/>c2</a></td> <td><a href=#6>row 2 column 3</a></td> </tr> </tabLe>

jhnc's user avatar

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.