How to make <div> fill <td> height
Asked Answered
T

7

133

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?

Trapes answered 22/8, 2010 at 15:46 Comment(1)
Related: #8345350Nilsson
S
261

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.

Solutrean answered 22/8, 2010 at 17:22 Comment(11)
While it seems to work fine in webkit, IE9 completely breaks.Idun
Work for me in IE11 only when I also set div to inline-block. Thanks!Agateware
Here's a solution that also works in Firefox: #36576346Dietz
To make it work in Firefox as well as in Chrome I had to use min-height: 1px; instead of height: 1px;Dirt
🤯 I am not sure whether I like CSS or hate itEuchre
10 years latter still the only solution out there :DBurdick
After 12 years latter this is helpful for me👍👌Hendricks
Works in Chrome, but can't get it to work in Firefox, even using the min-height suggestion mentioned above.Laky
Setting the <div>s <td>s and <tables>s to 100% works in both Chrome and Firefox for me. Source: social.msdn.microsoft.com/forums/en-US/…Laky
the fact that this answer works infuriates me. makes no sense but thank youAnimalist
This still works in 2024, also with height: 0Asbestosis
S
46

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());
});
  
Sucker answered 22/8, 2010 at 17:17 Comment(9)
That could work. Let me get back to you when I've tried. I did read up on the subject and understood that <div> 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.Trapes
Yes, that's exactly it. For the <div>'s height: 100% to work, the <td> (which is the <div>s parent) must have a specified height. And you're also right - jQuery would do it quite easily for you - see my updated example.Sucker
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.Trapes
Hah, if only I had a dollar for the number of times CSS has made me change my approach :)Sucker
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.Kinghood
@Kinghood trust me, you're not the only one.Sucker
position: relative on a <td> is buggy in Firefox.Bullfight
the jquery solution worked though only when I placed it at the end of the file, thanksMagdeburg
The jQuery solution is the best for all browsers and simplicity.Latrena
G
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>
Gona answered 22/8, 2010 at 17:19 Comment(4)
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.Dietz
It doesn't with Firefox. It seems only to work with Chrome.Disbud
That snippet doesn't work on Chromium either, at least nowadays (I'm using 63.0.3239.84).Hawkins
Setting display: inline-block will often make the div taller than the <td> 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.Sandiesandifer
C
0

Althrough this question/workaround are quite old but still working (& annoying), I would like to add something from spec.

As @psayre23 mentioned that adding 1px to "hack" table's height would force browser engine to actually calcuate td's height afterwards and fix this "issue". It looks not intuitive, but it's by design (and not limited to table):

From "Content height: the 'height' property" (CSS 2.1 spec), the <percentage> part says:

If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.

This sentence can also be found on MDN's height doc.

Counsellor answered 16/12, 2023 at 5:36 Comment(0)
H
-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');
}

}

Hallette answered 28/6, 2014 at 15:0 Comment(0)
T
-3

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

Tamas answered 14/5, 2017 at 9:15 Comment(0)
C
-5

Modify the background image of the <td> itself.

Or apply some css to the div:

.thatSetsABackgroundWithAnIcon{
    height:100%;
}
Cristoforo answered 22/8, 2010 at 15:48 Comment(1)
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 <dl>. 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)Trapes

© 2022 - 2024 — McMap. All rights reserved.