126

I've looked through several posts on StackOverflow, but haven't been able to find an answer to this rather simple question.

I have an HTML construct like this:

<table>
  <tr>
    <td class="thatSetsABackground">
      <div class="thatSetsABackgroundWithAnIcon">
        <dl>
          <dt>yada
          </dt>
          <dd>yada
          </dd>
        </dl>
      <div>
    </td>
    <td class="thatSetsABackground">
      <div class="thatSetsABackgroundWithAnIcon">
        <dl>
          <dt>yada
          </dt>
          <dd>yada
          </dd>
        </dl>
      <div>
    </td>
  </tr>
</table>

What I need is for the div to fill the height of the td, so I can be able to position the div's background (the icon) at the bottom-right corner of the td.

How do you suggest I go about that?

6 Answers6

248

If you give your TD a height of 1px, then the child div would have a heighted parent to calculate it's % from. Because your contents would be larger then 1px, the td would automatically grow, as would the div. Kinda a garbage hack, but I bet it would work.

psayre23
  • 2,766
  • 2
  • 16
  • 10
44

CSS height: 100% only works if the element's parent has an explicitly defined height. For example, this would work as expected:

td {
    height: 200px;
}

td div {
    /* div will now take up full 200px of parent's height */
    height: 100%;
}

Since it seems like your <td> is going to be variable height, what if you added the bottom right icon with an absolutely positioned image like so:

.thatSetsABackgroundWithAnIcon {
    /* Makes the <div> a coordinate map for the icon */
    position: relative;

    /* Takes the full height of its parent <td>.  For this to work, the <td>
       must have an explicit height set. */
    height: 100%;
}

.thatSetsABackgroundWithAnIcon .theIcon {        
    position: absolute;
    bottom: 0;
    right: 0;
}

With the table cell markup like so:

<td class="thatSetsABackground">  
  <div class="thatSetsABackgroundWithAnIcon">    
    <dl>
      <dt>yada
      </dt>
      <dd>yada
      </dd>
    </dl>
    <img class="theIcon" src="foo-icon.png" alt="foo!"/>
  </div>
</td>

Edit: using jQuery to set div's height

If you keep the <div> as a child of the <td>, this snippet of jQuery will properly set its height:

// Loop through all the div.thatSetsABackgroundWithAnIcon on your page
$('div.thatSetsABackgroundWithAnIcon').each(function(){
    var $div = $(this);

    // Set the div's height to its parent td's height
    $div.height($div.closest('td').height());
});
  
Kirk Beard
  • 9,569
  • 12
  • 43
  • 47
Pat
  • 25,237
  • 6
  • 71
  • 68
  • That could work. Let me get back to you when I've tried. I did read up on the subject and understood that
    needs a specified height to be able to scale to 100%. From what I read that was possible to do with jQuery though, since it can calculate it for me.
    –  Aug 23 '10 at 15:35
  • Yes, that's exactly it. For the `
    `'s height: 100% to work, the `` (which is the `
    `s parent) must have a specified height. And you're also right - jQuery would do it quite easily for you - see my updated example.
    – Pat Aug 23 '10 at 15:44
  • 2
    I didn't really work all that well, and we've decided on different approach. But I'll accept your answer since it's the best one around. –  Sep 15 '10 at 17:36
  • 3
    Hah, if only I had a dollar for the number of times CSS has made me change my approach :) – Pat Sep 15 '10 at 17:43
  • 7
    Am I the only one who thinks that "CSS height: 100% only works if the element's parent has an explicitly defined height" is a really dumb rule? The browser determines the parent element's height anyway; there's no way *you* should have to explicitly set the parent element's height. – Jez Nov 26 '12 at 17:47
  • @Jez trust me, you're not the only one. – Pat Nov 26 '12 at 18:45
  • `position: relative` on a `` is buggy in Firefox. – Radek Mar 18 '13 at 15:49
  • 1
    the jquery solution worked though only when I placed it at the end of the file, thanks – luke_mclachlan Jan 16 '16 at 20:15
  • The jQuery solution is the best for all browsers and simplicity. – Tom Bowen Sep 13 '16 at 10:29
3

You could try making your div float:

.thatSetsABackgroundWithAnIcon{

    float:left;
}

Alternativelly, use inline-block:

.thatSetsABackgroundWithAnIcon{

    display:inline-block;
}

Working example of the inline-block method:

table,
th,
td {
  border: 1px solid black;
}
<table>
  <tr>
    <td>
      <div style="border:1px solid red; height:100%; display:inline-block;">
        I want cell to be the full height
      </div>
    </td>
    <td>
      This cell
      <br/>is higher
      <br/>than the
      <br/>first one
    </td>
  </tr>
</table>
Wouter
  • 1,829
  • 3
  • 28
  • 34
angryobject
  • 418
  • 2
  • 7
  • The float:left suggestion doesn't seem to work. This answer could be improved by removing it, since the second solution mentioned seems to work. – Wouter Apr 12 '16 at 12:17
  • 1
    It doesn't with Firefox. It seems only to work with Chrome. – YLombardi Apr 27 '16 at 10:00
  • 10
    That snippet doesn't work on Chromium either, at least nowadays (I'm using 63.0.3239.84). – Michael Dec 11 '17 at 22:24
  • Setting `display: inline-block` will often make the div *taller* than the `` element would otherwise have been. In my case, this made this result a non-solution. I want a way to style the div that will make it *exactly* the height that the table cell would have been otherwise. In particular, this comes up if there is no text and are no other inline elements in the table row. – cazort Mar 16 '22 at 18:15
-2

Really have to do this with JS. Here's a solution. I didn't use your class names, but I called the div within the td class name of "full-height" :-) Used jQuery, obviously. Note this was called from jQuery(document).ready(function(){ setFullHeights();}); Also note if you have images, you are going to have to iterate through them first with something like:

function loadedFullHeights(){
var imgCount = jQuery(".full-height").find("img").length;
if(imgCount===0){
    return setFullHeights();
}
var loaded = 0;
jQuery(".full-height").find("img").load(function(){
    loaded++;
    if(loaded ===imgCount){
        setFullHeights()
    }
});

}

And you would want to call the loadedFullHeights() from docReady instead. This is actually what I ended up using just in case. Got to think ahead you know!

function setFullHeights(){
var par;
var height;
var $ = jQuery;
var heights=[];
var i = 0;
$(".full-height").each(function(){
    par =$(this).parent();
    height = $(par).height();
    var tPad = Number($(par).css('padding-top').replace('px',''));
    var bPad = Number($(par).css('padding-bottom').replace('px',''));
    height -= tPad+bPad;
    heights[i]=height;
    i++;
});
for(ii in heights){
    $(".full-height").eq(ii).css('height', heights[ii]+'px');
}

}

GoodNews
  • 35
  • 7
-3

This questions is already answered here. Just put height: 100% in both the div and the container td.

Community
  • 1
  • 1
Nacho Coloma
  • 7,070
  • 2
  • 40
  • 43
-5

Modify the background image of the <td> itself.

Or apply some css to the div:

.thatSetsABackgroundWithAnIcon{
    height:100%;
}
Jage
  • 7,990
  • 3
  • 32
  • 31
  • as I write in the code. The TD already has a background-image set using a class. So that option is not viable. I have tried setting the height of the div to 100%, but that does not work. It simply wraps to the variable height of the contained
    . So something is needed to make the div "understand" that it should fill the height. And height: 100% does not do that. (not alone atleast)
    –  Aug 22 '10 at 15:54