0
\$\begingroup\$

I want to create clickable rows in an html table. Each row should be a link leading to a different page. I can of course add onclick handler, but that will create kind of a crappy UI - poor accessibility, no keyboard navigation, no right/middle click...

I found a better way to do it. Instead of using normal table element, force divs to act as different table tags through css display rules. And for rows, use a-s, with appropriate href attribute.

Here's what I mean:

    
  .table {
    display: table;
    border-collapse: collapse;
    font-family: sans-serif;
    width: 100%;
  }
  .thead {
    display: table-header-group;
  }
  .tbody {
    display: table-row-group;
  }
  .td, .th {
    display: table-cell;
    padding: 5px 10px;
    text-align: center;
  }
  .tr {
    display: table-row;
  }
  .thead > .tr {
    background: #ccc;
    color: #555;
  }
  a.tr {
    text-decoration: none;
    color: black;
  }
  a.tr:hover {
    background: #eee;
    cursor: pointer;
  }
  <div class="table">
    <div class="thead">
      <div class="tr">
        <div class="th">ID</div>
        <div class="th">Name</div>
      </div>
    </div>
    <div class="tbody">
      <a class="tr" href="#">
        <div class="td">524</div>
        <div class="td">John Smith</div>
      </a>
      <a class="tr" href="#">
        <div class="td">331</div>
        <div class="td">Miles Corner</div>
      </a>
    </div>
  </div>

Note how rows are clickable, you can tab through them and there is a nice tooltip showing link you will go to. Much better than onclick.

If I use a framework like React, I don't even have to replace all elements with div-s. I can just add <a> tags instead of <tr>s and it will work.

My question is, what's the catch? What am I missing? Is there some accessibility, browser compatibility, or other reason not to do this?

\$\endgroup\$
1
1
\$\begingroup\$

If it's a table, make it a <table>. Write a traditional <tbody> containing <tr>, in turn containing <td>, in turn containing individual <a>. Then the text will be links. This is simpler, doesn't require any fancy CSS, and better communicates your intent to browsers.

All of the usual keyboard and mouse functionality will be preserved.

\$\endgroup\$
3
  • \$\begingroup\$ But I want the entire row to be clickable, not just a link inside a cell. That's the whole point of the pattern. \$\endgroup\$ – panta82 Apr 10 at 8:32
  • \$\begingroup\$ Well, you're concerned about crappy UIs. The text is part of the "foreground" and the cell background is part of the "background". I'd think that users would be less surprised by clickable text and a non-clickable background. Are you sure that the opposite is more user-friendly? \$\endgroup\$ – Reinderien Apr 10 at 13:48
  • \$\begingroup\$ This is example with minimal styling. In actual production app, table rows will look more like cards, with proper shadows and other effects, to make it clear they are clickable. I basically want fat card-like horizontal rows, but also to be laid out like table, with fluid columns. This is the only way I thought of to make that work (with all the a11y and other benefits links bring). \$\endgroup\$ – panta82 Apr 10 at 17:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.