Make link in table cell fill the entire row height
Asked Answered
R

10

76

I have a table of data and each cell is a link. I want to allow the user to click anywhere in the table cell and have them follow the link. Sometimes the table cells are more than one line but not always. I use td a {display: block} to get the link to cover most of the cell. When there is one cell in a row that is two lines and the others are only one line the one liners don't fill the entire vertical space of the table row. Here is the sample HTML and you can see it in action here http://www.jsfiddle.net/RXHuE/:

<head>
<style type="text/css">
  td {width: 200px}
  td a {display: block; height:100%; width:100%;}
  td a:hover {background-color: yellow;}
</style>
<title></title>
</head>
<body>
<table>
  <tbody>
    <tr>
      <td>
        <a href="http://www.google.com/">Cell 1<br>
        second line</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 2</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 3</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 4</a>
      </td>
    </tr>
  </tbody>
</table>
</body>
Redtop answered 19/10, 2010 at 7:6 Comment(3)
+1 That's the first time I've heard about "display: table".Maje
Yeah, I tried using "display: inline-block", which actually worked in Webkit browsers but not firefox or IE. Then I read that "display: table" is similar so I thought I would give it a try and ended up posting the question with that. I have since edited the question to use "display: block" because that was my first idea.Redtop
I nearly ask the same question: #9127774Monteverdi
H
47

You need a small change in your CSS. Making td height:100%; works for IE 8 and FF 3.6, but it doesn't work for Chrome.

td {
  width: 200px;
  border: solid 1px green;
  height: 100%
}
td a {
  display: block;
  height:100%;
  width:100%;
}

But making height to 50px works for Chrome in addition to IE and FF

td {
  width: 200px;
  border: solid 1px green;
  height: 50px
}
td a {
  display: block;
  height:100%;
  width:100%;
}

Edit:

You have given the solution yourself in another post here; which is to use display: inline-block;. This works when combined with my solution for Chrome, FF3.6, IE8

td {
  width: 200px;
  border: solid 1px green;
  height: 100%}
td a {
  display: inline-block;
  height:100%;
  width:100%;
}

Update

The following code is working for me in IE8, FF3.6 and chrome.

CSS

td {
  width: 200px;
  border: solid 1px green;
  height: 100%;
}
td a {
  display: inline-block;
  height:100%;
  width:100%;
}
td a:hover {
  background-color: yellow;
}

HTML

<table>
  <tbody>
    <tr>
      <td>
        <a href="http://www.google.com/">Cell 1<br>
        second line</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 2</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 3</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 4</a>
      </td>
    </tr>
  </tbody>
</table>

The example lays here

Haulage answered 19/10, 2010 at 7:50 Comment(12)
Good suggestion, however, I don't want to fix the height of the cells. I'm basically displaying a table of data to the user and sometimes a row has a cell with lots of data causing it to wrap but sometimes there are no such cells in a row.Redtop
@Brian: Does making height 100% is also not feasible for you?Haulage
@Gaurav: I can make the the td's and links 100% height, I just don't want to give them a set height (otherwise they will sometimes be taller than they need to be). Also that would be hilarious if I had given the answer somewhere else :).Redtop
@Brian: Really? Is it working for crome alone? I checked for IE8, FF 3.6 and Chrome. Anyway, I have pasted the html which is working for me in edit2.Haulage
Thanks Gaurav, I was dealing with this issue again recently and revisited your answer. It is working for me on IE9, FF9 and Chrome.Redtop
I know I'm late to the party, but Gaurav's solution is incorrect. This solution is assuming you will wrap the content of the cell using a <br> tag, and that's just not the case in scalable circumstances because we never know where the text is going to wrap. Here's a DEMO of the exact same code Gaurav provided but without the <br> inside the text: it doesn't make the anchor links expand the entire height of the <td>. For what I've read all over the web, this is not doable today; right now Tim Büthe's solution below with JS seems to be the best solutionEndolymph
Hate to say it but zobier's answer below is THE answer to this issue. No need for JavaScript at all.Endolymph
Unfortunately, the example linked only works in quirks mode. Put <!DOCTYPE html> at the top of the document and it breaks.Idaidae
Does not work in Firefox 24 and standards mode. Need to search for something else.Wondrous
@Ricardo I never put a <br>. It is in the question.Haulage
td{ position: relative } and td a{position: absolute; display:block; width: 100%; height: 100% } for very hight cellDotson
what if i dont set td height?Li
L
111

Set an arbitrarily large negative margin and equal padding on the block element and overflow hidden on the parent.

td {
    overflow: hidden;
}
td a {
    display: block;
    margin: -10em;
    padding: 10em;
}

http://jsfiddle.net/RXHuE/213/

Loris answered 4/4, 2013 at 1:31 Comment(7)
I like this one. I'm not using no JS.Lyricism
Works great in current Firefox (27), Chrome (33) and IE (11).Fullmouthed
Best solution. Also allows you to still vertically center the text, which other solutions seem to have problems with. The ONLY problem is that on Chrome for Android (and maybe other browsers too) when you tap a link the whole big link gets higlighted, including the parts outside the <a>. Fixable with -webkit-tap-highlight-color: rgba(0, 0, 0, 0);Lowborn
This is clever, but unfortunately breaks if you're using table cells for a responsive navigation, and you need dropdown menus from that navigation.Madelynmademoiselle
Outstanding. Allows the browser's rendering engine to continue sizing table cells to fit the space occupied by the table, which is crucial for something like generating calendars, which may have a variable number of rows depending on the month. This neatly solves a sticky formatting problem. My hat's off to you, zobier.Gratulation
display: block;margin: -10em;padding: 10em;height:100%;width:100%; Did the trick for me for IE 7. Thanks :)Insured
When you move the mouse above a cell on the top-row doesn't this mean the link can be clicked even by clicking above the cell? Why exactly is 10em the magic number? Why not 1em or 100em?Trapan
H
47

You need a small change in your CSS. Making td height:100%; works for IE 8 and FF 3.6, but it doesn't work for Chrome.

td {
  width: 200px;
  border: solid 1px green;
  height: 100%
}
td a {
  display: block;
  height:100%;
  width:100%;
}

But making height to 50px works for Chrome in addition to IE and FF

td {
  width: 200px;
  border: solid 1px green;
  height: 50px
}
td a {
  display: block;
  height:100%;
  width:100%;
}

Edit:

You have given the solution yourself in another post here; which is to use display: inline-block;. This works when combined with my solution for Chrome, FF3.6, IE8

td {
  width: 200px;
  border: solid 1px green;
  height: 100%}
td a {
  display: inline-block;
  height:100%;
  width:100%;
}

Update

The following code is working for me in IE8, FF3.6 and chrome.

CSS

td {
  width: 200px;
  border: solid 1px green;
  height: 100%;
}
td a {
  display: inline-block;
  height:100%;
  width:100%;
}
td a:hover {
  background-color: yellow;
}

HTML

<table>
  <tbody>
    <tr>
      <td>
        <a href="http://www.google.com/">Cell 1<br>
        second line</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 2</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 3</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 4</a>
      </td>
    </tr>
  </tbody>
</table>

The example lays here

Haulage answered 19/10, 2010 at 7:50 Comment(12)
Good suggestion, however, I don't want to fix the height of the cells. I'm basically displaying a table of data to the user and sometimes a row has a cell with lots of data causing it to wrap but sometimes there are no such cells in a row.Redtop
@Brian: Does making height 100% is also not feasible for you?Haulage
@Gaurav: I can make the the td's and links 100% height, I just don't want to give them a set height (otherwise they will sometimes be taller than they need to be). Also that would be hilarious if I had given the answer somewhere else :).Redtop
@Brian: Really? Is it working for crome alone? I checked for IE8, FF 3.6 and Chrome. Anyway, I have pasted the html which is working for me in edit2.Haulage
Thanks Gaurav, I was dealing with this issue again recently and revisited your answer. It is working for me on IE9, FF9 and Chrome.Redtop
I know I'm late to the party, but Gaurav's solution is incorrect. This solution is assuming you will wrap the content of the cell using a <br> tag, and that's just not the case in scalable circumstances because we never know where the text is going to wrap. Here's a DEMO of the exact same code Gaurav provided but without the <br> inside the text: it doesn't make the anchor links expand the entire height of the <td>. For what I've read all over the web, this is not doable today; right now Tim Büthe's solution below with JS seems to be the best solutionEndolymph
Hate to say it but zobier's answer below is THE answer to this issue. No need for JavaScript at all.Endolymph
Unfortunately, the example linked only works in quirks mode. Put <!DOCTYPE html> at the top of the document and it breaks.Idaidae
Does not work in Firefox 24 and standards mode. Need to search for something else.Wondrous
@Ricardo I never put a <br>. It is in the question.Haulage
td{ position: relative } and td a{position: absolute; display:block; width: 100%; height: 100% } for very hight cellDotson
what if i dont set td height?Li
B
8

Little late to the party, but there's a nice solution I just discovered.

You can use a combination of relative and absolute positioned elements, along with a pseudo element to get the effect you're looking for. No extra markup needed!

Change the table cell (<td>), to be position: relative;, and create a ::before or ::after pseudo element on the <a> tag, and set it to position: absolute;, and also use top: 0; left: 0; right: 0; bottom: 0;.

Because the pseudo element is attached to the anchor tag, and you're telling it to take up the entire table cell, it will force the anchor tag to be at least that size, whilst not affecting the actual content of the anchor tag itself (thereby retaining its vertically centered alignment).

For example

table {
  border-collapse: collapse;
  table-layout: fixed;
}

td {
  position: relative;
  width: 200px;
  padding: 0.5em 1em;
  border: 2px solid red;
  
  background-color: lime;
}

td a {
  /* FONT STYLES HERE */
  text-decoration: none;
}

td a::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
}
<table>
  <tbody>
    <tr>
      <td>
        <a href="http://www.google.com/">Cell 1<br>
        second line</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 2</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 3</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 4</a>
      </td>
    </tr>
    <tr>
      <td>
        <a href="http://www.google.com/">Cell 5</a>
      </td>
      <td>
        <a href="http://www.google.com/">Cell 6<br>
        second line</a>
      </td>
    </tr>
  </tbody>
</table>

Hope this helps!

Britanybritches answered 3/9, 2017 at 12:54 Comment(5)
This appears to stretch the clickable region but not extend the background color: i.imgur.com/NDO61sV.pngDodecagon
Apply the background color to the after element too... td a, td a:after { background-color: red; }Britanybritches
You may also need to adjust the z-index of the ::before or ::after pseudo element used, so that the background color doesn't block you from seeing the actual contents of the cell.Roxana
@Roxana - @Dodecagon - Improving on my previous comment, adjusting the background-color on the td instead of the a tag is much easier, and better practice than messing with z-index's. See the reworked example in my answer.Britanybritches
This works perfectly for me. Should be the accepted answer - the WHOLE td is clickable. Although I did have to add display: block to my a link style to get it to look right.Idaidae
I
4

Following hack works [Tested on Chrome / Firefox / Safari] Have the same padding for td and anchor elements. And for anchor also have margin which is equal to -ve of padding value.

HTML

<table>
    <tr>
        <td><a>Hello</a></td>
    </tr>
</table>

CSS:

td {                          
    background-color: yellow;                                                                              
    padding: 10px;                                                                                                            
}  
a {
    cursor:pointer;
    display:block;
    padding: 10px;
    margin: -10px;
}

Working Fiddle :http://jsfiddle.net/JasYz/

Ironing answered 11/4, 2013 at 22:32 Comment(0)
M
1

Try display: block:

td a {display: block; height:100%;}

[EDIT] WTF ... I can confirm this doesn't work in FF 4 and Chrome. This works:

td a {display: block;  height: 2.5em; border: 1px solid red;}

That suggests that height:100%; isn't defined in a table cell. Maybe this is because the cell gets its size from the content (so the content can't say "tell me your size" because that would lead to a loop). It doesn't even work if you set a height for the cells like so:

td {width: 200px; height: 3em; padding: 0px}

Again the code above will fail. So my suggestion is to use a defined height for the links (you can omit the width; that is 100% by default for block elements).

[EDIT2] I've clicked through a hundred examples at http://www.cssplay.co.uk/menus/ but none of them mix single line and multi-line cells. Seems like you hit a blind spot.

Maje answered 19/10, 2010 at 7:10 Comment(6)
Thanks for the suggestion. That is actually what I tried first and I changed the code in my post to use that. That allows the link to take up the entire horizontal space of the table cell, but not the vertical.Redtop
@Brian Fisher: Then something else is wrong. Add a border around the table cells and the links to see how big they really are. If the link is the only element in the cell and the cell has no padding, etc. height: 100%; should do the trick.Maje
@Brian: Or to put it another way: The cell should get the height from the link in the code above, so you can never have any space outside of the link.Maje
So I put a border around the cell, and it looks like the cell is not filling the entire height of the row. I tried putting height: 100% on the td but that didn't work. Any other thoughts?Redtop
It works for me if I fix the height of the td and just set the height of the td a to 100% in IE 8, FF3.6 and Chrome. I don't really want to fix the height of the td's because sometimes the rows will be 1, 2 or 3 lines depending on the content. WTF is awesome, I would give you plus 2 if I could.Redtop
Post the question on doctype.com Maybe someone there knows a trick to make it work without nailing the height down. Otherwise, you'll need JavaScript shudderMaje
E
1

I will post the same answer here, as I did on my own question.

Inspired by Jannis M's answer, I did the following:

$(document).ready(function(){    
    $('table tr').each(function(){
        var $row = $(this);
        var height = $row.height();
        $row.find('a').css('height', height).append('&nbsp;');  
    });       
});

I added a &nbsp; since empty links (not containing text nodes) can not be styled(?).

See my updated fiddle.

Erna answered 6/2, 2012 at 11:30 Comment(1)
You should check out Gaurav Saxena answer, it is a CSS only solution that works well on all current browsers.Redtop
P
0

Only problem here is that using display: block forces the browser to ignore the vertical align: center...

oops.

I jury rigged it to look right for one cell with height:60 and a font that occupied 20 pixels by adding a br... Then I realized that I had some items with 2-line text. Dang.

I ended up using the javascript. The javascript doesn't give the nice mousey pointy clicker thing, but the line of text does, so it will actually trigger a visual response, just not where I want it to... Then the Javascript will catch all the clicks that 'miss' the actual href.

Maybe not the most elegant solution, but it works well enough for now.

Now if I could only figure out how to do this the right way....

Any ideas on how to add the mouse icon change to a hand for the area covered by the onclick? Right now, the click to page works, but the icon only changes when it hits the href which only affects the text.

Pape answered 16/3, 2013 at 9:31 Comment(0)
C
0

Why don't you just get rid of the <a> altogheter and add an onClick to the <td> directly?

<head>
<style type="text/css">
td {
    text-align:center;
}
td:hover {
    cursor:pointer;
    color:#F00;
}
</style>
<title></title>
</head>
<body>
<table>
    <tbody>
        <tr>
            <td onclick="location.href='http://www.google.com/';">Cell 1<br />second line</td>
            <td onclick="location.href='http://www.google.com/';">Cell 2</a></td>
            <td onclick="location.href='http://www.google.com/';">Cell 3</td>
            <td onclick="location.href='www.google.com';">Cell 4</td>
        </tr>
    </tbody>
</table>

This way you cut out the middle man.

PS: i know this was asked and answered many years ago, but none of the answers above solved the problem in my case. Hope this helps someone.

Convert answered 4/9, 2015 at 8:35 Comment(4)
This isn't keyboard accessible.Doubleheader
Being keyboard accessible wasn't part of the requirement, or have I missed something?Convert
All functionality should be available through a keyboard, according to WCAG. Some users prefer to, or need to, access content through their keyboard.Doubleheader
For me this was good enough since the site isn't public and I don't care about accessibility there. So, WCAG out the door and this answer actually different and good solution than all the ones above +1Nonbeliever
W
0

For me the only solution is to replace <table> <tr> with <div>s and style them using display:table and display:table-row accordingly.

Then you can replace <td> with just <a> and style it with display:table-cell.

Work perfectly even on varying heights of <td> contents.

so original html without anchors:

<table>
  <tr>
    <td>content1<br>another_line</td>
    <td>content2</td>
  </tr>
</table>

now becomes:

a:hover
{
  background-color:#ccc;
}
    <div style="display:table; width:100%">
      <div  style="display:table-row">
        <a href="#" style="display:table-cell; border:solid 1px #f00">content1<br>another_line</a>
        <a href="#" style="display:table-cell; border:solid 1px #f00">content2</a>
      </div>
    </div>
Windhoek answered 28/4, 2016 at 8:51 Comment(0)
B
0

I have used this solution: works better then the rest in my case.

CSS:

.blocktd {width: 100%; height: 100%; padding: 0px; overflow: hidden}

a.blocktd {margin: 0em;  padding: 50px 20px 50px 20px; display: block;}

a.blocktd:hover {border: 4px solid #70AEE8; border-radius: 10px; padding: 46px 16px 46px 16px; transition:  0.2s;}

And in HTML: <a href="..." class="blocktd">...</a>

Bluecoat answered 28/10, 2020 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.