Wrapping HTML table rows in <a> tags

Is it possible to wrap entire table rows in <a> tags? I want the the entire row to be a clickable link.

If I try the following, the links get rendered above and outside the table:

This:

<table>
<a href="value_url"><tr><td>value</td><td>value</td></tr></a>
<a href="value_url"><tr><td>value</td><td>value</td></tr></a>
</table>

Renders like this:

<a href="value_url"></a>
<a href="value_url"></a>
<table>
<tr><td>value</td><td>value</td></tr>
<tr><td>value</td><td>value</td></tr>
</table>

Solution 1:

Edit 2021:
It seems nowadays there's better options that are more semantic and more screen-reader-friendly. Check out e.g. Jans solution.

Original answer:
as a link in each td is not a good alternative and using js is a bit dirty, here is another html/css approach:

HTML:

<div class="table">
    <a class="table-row" href="/mylink">
        <div class="table-cell">...</div>
        <div class="table-cell">...</div>
        <div class="table-cell">...</div>
    </a>
</div>

CSS:

.table { display:table; }
.table-row { display:table-row; }
.table-cell { display:table-cell; }

Solution 2:

It renders like that because the browser is respecting the W3C specification and only allowing <tr> tags as direct descendents of <table>.

As a solution, you could either put an <a> tag inside each <td> that points to the same URL:

<table>
    <tr>
        <td>
            <a href="http://url/stuff">
                First column
            </a>
        </td>
        <td>
            <a href="http://url/stuff">
                Second column
            </a>
        </td>
    </tr>
</table>

Or you could bind an onClick handler to the <tr> with JavaScript. A jQuery example would be this:

$('table tr').click(function() {
    window.location = 'http://location/here';
});

Or, even better, use delegated events (jQuery 1.7+):

$('table').on('click', 'tr', function() {
    window.location = 'http://location/here';
});

Solution 3:

Another simple, CSS only solution is turning <a> into block elements

<tr>
  <td><a href="#">name 1</a></td><td><a href="#">link 1</a></td>    
</tr>
<tr>
  <td><a href="#">name 2</a></td><td><a href="#">link 2</a></td>    
</tr>

The CSS would be:

td > a {
  display: block;
}

Then the <a> would take up the entire <td>, and making entire row clickable without JS if the link is repeated for each cell in a row.

https://jsfiddle.net/evwa451n/

Solution 4:

It's invalid HTML to have any elements other than thead,tbody or tfoot as a direct child of a table, and those elements have only tr as their valid children.

Any other content must be inside of a td or th to be valid.

What you're seeing is the browser restructuring your DOM so that it's as valid as it can be. The problem with relying on that behaviour though is that different browsers react in different ways.

If you need a tr to be interactive (and for clicks on those elements to lead somewhere/do something) you should use JavaScript.

But, short answer, yes you can do it, but it's not valid to do so, so please don't.

For interactive table rows, though, one solution (in plain JavaScript):

var rows = document.getElementsByTagName('tr'),
    url;

for (var i=0,len=rows.length; i<len; i++){
    rows[i].onclick = function(){
        uri = this.getAttribute('data-url');
        window.location = uri;
    };
}

JS Fiddle demo.

(Which, obviously, requires that the tr elements have a data-url attribute to specify where they should link to.)

Solution 5:

You could use onclick, so you can get the content dynamically

<td onclick="window.location='http://www.google.com';" style='cursor: pointer;'>Hello</td>

http://jsfiddle.net/ankJw/