55

I know it is possible to link an entire table cell with CSS.

.tableClass td a{
   display: block;
}

Is there a way to apply a link to an entire table row?

santa
  • 12,234
  • 49
  • 155
  • 255

8 Answers8

45

I agree with Matti. Would be easy to do with some simple javascript. A quick jquery example would be something like this:

<tr>
  <td><a href="http://www.example.com/">example</a></td>
  <td>another cell</td>
  <td>one more</td>
</tr>

and

$('tr').click( function() {
    window.location = $(this).find('a').attr('href');
}).hover( function() {
    $(this).toggleClass('hover');
});

then in your CSS

tr.hover {
   cursor: pointer;
   /* whatever other hover styles you want */
}
Community
  • 1
  • 1
Jeff
  • 4,136
  • 23
  • 32
  • 3
    It may work for me, but it's on click. Can it also behave like a link on hover? Thanks. – santa Feb 05 '11 at 04:03
  • sure, what I'd probably do is add a class on hover and add whatever styling you want within that class. I'll update my post with an example. – Jeff Feb 05 '11 at 13:36
  • 47
    This solution has a lot of problems. For example, you can’t right-click on any of the “other” table cells and choose “copy link”, “open in new tab” or whatever. Also, you can’t shift-click/control-click/command-click the row to make it open in a new tab, because the click event will trigger nevertheless and cause _both_ the current _and_ the new tab to navigate to the target page. – scy Mar 05 '12 at 16:02
  • That solution works perfectly for me, especially on a mobile device, which doesn't require any of the "shift-click" downsides that Scytale mentioned. – Sterling Bourne Jun 07 '13 at 15:17
  • 3
    [Here is a solution that only needs HTML and CSS.](http://stackoverflow.com/a/23120665/2463800) Hope this helps. – Trevin Avery Apr 16 '14 at 21:42
  • jibruno, change .hover to :hover – Tommz Aug 06 '14 at 17:43
  • @scy But what is the alternative? – rybo111 Aug 20 '14 at 09:53
  • @scy Actually, on further thought, the solution is simple. Add `` to all the values of the table. – rybo111 Aug 20 '14 at 09:56
33

Use the ::before pseudo element. This way only you don't have to deal with Javascript or creating links for each cell. Using the following table structure

<table>
  <tr>
    <td><a href="http://domain.tld" class="rowlink">Cell</a></td>
    <td>Cell</td>
    <td>Cell</td>
  </tr>
</table>

all we have to do is create a block element spanning the entire width of the table using ::before on the desired link (.rowlink) in this case.

table {
  position: relative;
}

.rowlink::before {
  content: "";
  display: block;
  position: absolute;
  left: 0;
  width: 100%;
  height: 1.5em; /* don't forget to set the height! */
}

demo

The ::before is highlighted in red in the demo so you can see what it's doing.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Elliott
  • 2,479
  • 2
  • 21
  • 13
  • 1
    This is a much cleaner solution than everything above. Curious: how would you adjust this for `td` with `padding-top`? – eirikir Oct 08 '15 at 22:11
  • @eirikir Adding a negative `margin-top` to `.rowlink::before` equal to the `padding-top` of `td` worked for me. – jzzocc May 20 '16 at 19:40
  • Great stuff, best solution I've seen to this by far. – logos May 19 '17 at 04:56
  • 1
    Looks very nice. Always best to not rely on javascript! One caveat: from the markup point of view, the contents of the other cells are not in the anchor. This might impact usability (and perhaps SEO) in some cases. And it does not work in non-css agents. – Marten Koetsier Jun 22 '17 at 13:49
25

Unfortunately, no. Not with HTML and CSS. You need an a element to make a link, and you can't wrap an entire table row in one.

The closest you can get is linking every table cell. Personally I'd just link one cell and use JavaScript to make the rest clickable. It's good to have at least one cell that really looks like a link, underlined and all, for clarity anyways.

Here's a simple jQuery snippet to make all table rows with links clickable (it looks for the first link and "clicks" it)

$("table").on("click", "tr", function(e) {
    if ($(e.target).is("a,input")) // anything else you don't want to trigger the click
        return;

    location.href = $(this).find("a").attr("href");
});
Matti Virkkunen
  • 63,558
  • 9
  • 127
  • 159
  • @Aliester: With the JS method there should be no gaps... AFAIK. Besides, who has space between cells these days anyways – Matti Virkkunen Feb 05 '11 at 03:35
  • ack you are right missed that you were keying off the click event of the table row. (= – Adrian Feb 05 '11 at 03:40
  • For large number of elements, like `tr`, `delegate` is much more efficient than using `live` – Yi Jiang Feb 05 '11 at 05:02
  • 2
    @Yi Jiang: Are you sure...? AFAIK `live` just attaches one event handler onto the document level and that handles everything. Now, `live` can get inefficient if you have a lot of *handlers*, because they'll all be processed for essentially all events of the type, but the amount of elements should make no difference. – Matti Virkkunen Feb 05 '11 at 05:04
  • Indeed if I click on a different cell it works like a link but does just refreshes the same page. Also, is it possible to also make it look a link? Perhaps add a cursor: pointer to all TDs? – santa Feb 05 '11 at 05:18
  • @MattiVirkkunen Yes, you're right, the number of elements doesn't matter, that was my mistake there, but the complexity of the DOM structure does matter here, since all events will have to bubble through the entire document tree to reach the root element, while `delegate` is attached to the `table` element, and the events only need to bubble through one element – Yi Jiang Feb 05 '11 at 05:19
22

Example: http://xxjjnn.com/linktablerow.html

Link entire row:

<table>
  <tr onclick="location.href='SomeWherrrreOverTheWebsiiiite.html'">**
    <td> ...content... </td>
    <td> ...content... </td>
    ...
  </tr>
</table>

Iff you'd like to do highlight on mouseover for the entire row, then:

<table class="nogap">
  <tr class="lovelyrow" onclick="location.href='SomeWherrrreOverTheWebsiiiite.html'">**
     ...
  </tr>
</table>

with something like the following for css, which will remove the gap between the table cells and change the background on hover:

tr.lovelyrow{
  background-color: hsl(0,0%,90%);
}

tr.lovelyrow:hover{
  background-color: hsl(0,0%,40%);
  cursor: pointer;
}

table.nogap{
  border-collapse: collapse;
}

Iff you are using Rails 3.0.9 then you might find this example code useful:

Sea has many Fish, Fish has many Scales, here is snippet of app/view/fish/index.erb

<table>
<% @fishies.each do |fish| %>
  <tr onclick="location.href='<%= sea_fish_scales_path(@sea, fish) %>'"> 
    <td><%= fish.title %></td>
  </tr>
<% end %>
</table>

with @fishies and @sea are defined in app/controllers/seas_controller.rb

xxjjnn
  • 14,591
  • 19
  • 61
  • 94
12

Also it depends if you need to use a table element or not. You can imitate a table using CSS and make an A element the row

<div class="table" style="width:100%;">
  <a href="#" class="tr">
    <span class="td">
      cell 1
    </span>
    <span class="td">
      cell 2
    </span>
  </a>
</div>

css:

.table{display:table;}
.tr{display:table-row;}
.td{display:table-cell;}
.tr:hover{background-color:#ccc;}
Sidupac
  • 651
  • 7
  • 11
10

I feel like the simplest solution is sans javascript and simply putting the link in each cell (provided you don't have massive gullies between your cells or really think border lines). Have your css:

.tableClass td a{
   display: block;
}

and then add a link per cell:

<table class="tableClass">
    <tr>
        <td><a href="#link">Link name</a></td>
        <td><a href="#link">Link description</a></td>
        <td><a href="#link">Link somthing else</a></td>
    </tr>
</table>

boring but clean.

JeffJenk
  • 2,575
  • 2
  • 21
  • 28
3

To link the entire row, you need to define onclick function on your row, which is <tr>element and define a mouse hover in the CSS for tr element to make the mouse pointer to a typical click-hand in web:

In table:

<tr onclick="location.href='http://www.google.com'">
<td>blah</td>
<td>blah</td>
<td><strong>Text</strong></td>
</tr>

In related CSS:

tr:hover {
cursor: pointer;
}
Feri
  • 230
  • 4
  • 11
1

I think this might be the simplest solution:

<tr onclick="location.href='http://www.mywebsite.com'" style="cursor: pointer">
<td>...</td>
<td>...</td>
</tr>

The cursor CSS property sets the type of cursor, if any, to show when the mouse pointer is over an element.

The inline css defines that for that element the cursor will be formatted as a pointer, so you don't need the 'hover'.

Paulo Belo
  • 3,759
  • 1
  • 22
  • 20