ChatGPT解决这个技术问题 Extra ChatGPT

Make a DIV fill an entire table cell

css

I've seen this question and googled a bit, but nothing so far has worked. I figure it's 2010 now (those questions/answers are old and, well, unanswered) and we have CSS3! Is there any way to get a div to fill an entire table cell's width and height using CSS?

I don't know what the width and/or height of the cell will be ahead of time, and setting the div's width and height to 100% does not work.

Also, the reason I need the div is because I need to absolutely position some elements outside of the cell, and position: relative does not apply to tds, so I need a wrapper div.

Does the container of the table itself have a specific height? Does the table span the viewport of the page?
It is really odd that setting the height and width to 100% doesn't work. That should make the div the full width and height of the parent tag. Maybe this isn't working because of the relative positioning. I'm curious to see the solution when someone finds it.
@meder the data in the table is dynamic, so i will never know the height. the width fills the screen, yes.
You might want to look at this question: stackoverflow.com/questions/2841484/…
@Marcin If the height of the table-cell (ie. the container) is not explicitly stated then a pc% height on the inner DIV is actually computed as 'auto' - according to the spec.

D
Dai

I had to set a fake height to the <tr> and height: inherit for <td>s

tr has height: 1px (it's ignored anyway)

Then set the td height: inherit

Then set the div to height: 100%

This worked for me in IE edge and Chrome:

Something big with multi lines and makes table bigger
full-height div


I don't know if this always works, but it did work for me in IE 11.
I just needed td { height: 1px } for Chrome.
This doesn't work for Firefox, you have to set height: 100% instead of inherit on th/td cell. But then it won't work in chrome/safari etc. :-). I have used @supports (height: -mo-available) to actually target firefox and set the height in the query.
F
Flimm

div height=100% in table cell will work only when table has height attribute itself.

cell1cell2
long text long text long text long text long text long text

UPD in FireFox you should also set height=100% value to the parent TD element


Good trick, but worked only on Chromium for me. IE9 & firefox 19 aren't able to stretch the div.
instead of using a pixel height, i used 100% height and a min-height:1px.
If you set the containing td height to 100% as well, it should work in FF. This is the correct answer.
Downvoted, doesn't work. Fiddle: jsfiddle.net/Darker/da8aL2hk Screenshot: i.stack.imgur.com/CwLnK.png
You'll need to add a 100% height to the <tr> as well.
K
Krease

The following code works on IE 8, IE 8's IE 7 compatibility mode, and Chrome (not tested elsewhere):

<table style="width:100px"> <!-- Not actually necessary; just makes the example text shorter -->
   <tr><td>test</td><td>test</td></tr>
   <tr>
      <td style="padding:0;">
         <div style="height:100%; width:100%; background-color:#abc; position:relative;">
            <img style="left:90px; position:absolute;" src="../Content/Images/attachment.png"/>
            test of really long content that causes the height of the cell to increase dynamically
         </div>
      </td>
      <td>test</td>
   </tr>
</table>

You said in your original question that setting width and height to 100% didn't work, though, which makes me suspect that there is some other rule overriding it. Did you check the computed style in Chrome or Firebug to see if the width/height rules were really being applied?

Edit

How foolish I am! The div was sizing to the text, not to the td. You can fix this on Chrome by making the div display:inline-block, but it doesn't work on IE. That's proving trickier...


sigh... good call on checking if other styles were being applied. apparently i had some padding rules that were preventing my div from spanning the whole table cell. once i got rid of those, i had no problems. i was curious because my code looks just like yours (using classes of course), but when i went further up the chain, lo and behold, padding. thanks for your help.
try this example: jsfiddle.net/2K2tG notice how the cell w/the image is red and not #abc. width/height 100% does nothing
Yeah this works with Chrome, but not for Firefox unfortunately... jsfiddle.net/38Ngn/1
M
Madeorsk

So, because everyone is posting their solution and none was good for me, here is mine (tested on Chrome & Firefox).

table { height: 1px; } /* Will be ignored, don't worry. */
tr { height: 100%; }
td { height: 100%; }
td > div { height: 100%; }

Fiddle: https://jsfiddle.net/nh6g5fzv/

--

Edit: one thing you might want to note, if you want to apply a padding to the div in the td, you must add box-sizing: border-box; because of height: 100%.


Worked great for a while in my case, until recently Chrome started actually cutting down the table's height to 1px, effectively making it unusable. Not entirely sure what is going on here, just be careful when using this
I'm testing on Chromium 87 and it's still working, are you sure that your table still has display: table;? Or maybe we need to try on a development version of Chrome?
This works for me in Firefox, Chrome, Safari and Edge. Thanks
M
Matt Browne

If your reason for wanting a 100% div inside a table cell was to be able to have a background color extend to the full height but still be able to have spacing between the cells, you could give the <td> itself the background color and use the CSS border-spacing property to create the margin between the cells.

If you truly need a 100% height div, however, then as others here have mentioned you need to either assign a fixed height to the <table> or use Javascript.


you could space the cell by using border-spacing:5px on the "table"ed element, but I agree, using a DIV inside the cells is much more elegant and overall better to have.
thanks for the suggestion, works just fine. just remember to apply border-collapse: separate to the table, otherwise it wont have any effect. +1
border-collapse: separate is the default, but yes, that's a good tip.
m
mrbinky3000

Since every other browser (including IE 7, 8 and 9) handles position:relative on a table cell correctly and only Firefox gets it wrong, your best bet is to use a JavaScript shim. You shouldn’t have to alter your DOM for one failed browser. People use shims all the time when IE gets something wrong and all the other browsers get it right.

Here is a snippet with all the code annotated. The JavaScript, HTML and CSS use responsive web design practices in my example, but you don’t have to if you don’t want. (Responsive means it adapts to your browser width.)

http://jsfiddle.net/mrbinky3000/MfWuV/33/

Here is the code itself, but it doesn’t make sense without the context, so visit the jsfiddle URL above. (The full snippet also has plenty of comments in both the CSS and the Javascript.)

$(function() {
    // FireFox Shim
    if ($.browser.mozilla) {
        $('#test').wrapInner('<div class="ffpad"></div>');
        function ffpad() {
            var $ffpad = $('.ffpad'),
                $parent = $('.ffpad').parent(),
                w, h;
            $ffpad.height(0);
            if ($parent.css('display') == 'table-cell') {               
                h = $parent.outerHeight();
                $ffpad.height(h);
            }
        }
        $(window).on('resize', function() {
            ffpad();
        });
        ffpad();
    }
});

While this was a good answer, do not copy/paste this code. $.browser has been deprecated since jQuery 1.8 and was removed in 1.9. For more info: api.jquery.com/jQuery.browser
I like this answer as well, but like @cmegown said, $.browser is now deprecated. What I'd personally do instead(I'll try that - I'm not 100% sure it will work) would be to change the positioning of the element from static to absolute(or the other way around) and see if there is a change in the position of the element compared to the window. This should only work if the element has top:0; left: 0;.
I can confirm that that worked for me - I get the element's .offset() and then change it to position absolute and get it's offset() again and if it's not the same, I wrap it up in a position: relative div. This only works because when positioned absolutely I don't expect my element to change it's positioning(since it's top: 0; left: 0;)
Firefox does not "get it wrong". Relatively positioning a table cell is undefined in the CSS spec. (link)
E
Edward Newsome

if <table> <tr> <td> <div> all have height: 100%; set, then the div will fill the dynamic cell height in all browsers.


Why does this work?? 😭
J
Jata

after several days searching I figured out a possible fix for this issue.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Documento sin título</title>
</head>

<body style="height:100%">
<!-- for Firefox and Chrome compatibility set height:100% in the containing TABLE, the TR parent and the TD itself. -->
<table width="400" border="1" cellspacing="0" cellpadding="0" style="height:100%;">  
  <tr>
    <td>whatever</td>
    <td>whatever</td>
    <td>whatever</td>
  </tr>
  <tr style="height:100%;">
    <td>whatever dynamic height<br /><br /><br />more content
</td>
    <td>whatever</td>

    <!-- display,background-color and radius properties in TD BELOW could be placed in an <!--[if IE]> commentary If desired.
    This way TD would remain as display:table-cell; in FF and Chrome and would keep working correctly.    
    If you don't place the properties in IE commentary it will still work in FF and Chorme with a TD display:block;

    The Trick for IE is setting the cell to display:block; Setting radius is only an example of whay you may want a DIV 100%height inside a Cell.
    -->

    <td style="height:100%; width:100%; display:block; background-color:#3C3;border-radius: 0px 0px 1em 0px;">

    <div style="width:100%;height:100%;background-color:#3C3;-webkit-border-radius: 0px 0px 0.6em 0px;border-radius: 0px 0px 0.6em 0px;">
    Content inside DIV TAG
    </div>
     </td>
  </tr>
</table>
</body>
</html>

Spanish language: El truco es establecer la Tabla, el TR y el TD a height:100%. Esto lo hace compatible con FireFox y Chrome. Internet Explorer ignora eso, por lo que ponemos la etiqueta TD como block. De esta forma Explorer sí toma la altura máxima.

English explanation: within the code commentaries


v
vsync

I propose a solution using the experimental Flexbox to simulate a table layout which will allow a cell's content element to fill up its parent cell vertically:

Demo

.table{ display:flex; border:2px solid red; } .table > *{ flex: 1; border:2px solid blue; position:relative; } .fill{ background:lightgreen; height:100%; position:absolute; left:0; right:0; } /* Reset */ *{ padding:0; margin:0; } body{ padding:10px; }


b
booellean

Because I do not have enough reputation to post a comment, I want to add a complete cross-browser solution that combined @Madeorsk and @Saadat's approaches with some slight modification! (Tested on Chrome, Firefox, Safari, IE, and Edge as of 2/10/2020)

table { height: 1px; }
tr { height: 100%; }
td { height: 100%; }
td > div { 
   height: -webkit-calc(100vh);
   height: -moz-calc(100vh);
   height: calc(100%);
   width: 100%;
    background: pink;  // This will show that it works!
} 

However, if you're like me, than you want to control vertical alignment as well, and in those cases, I like to use flexbox:

td > div {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

F
FlorianB

Ok nobody mentioned this so I figured I would post this trick:

.tablecell {
    display:table-cell;
}
.tablecell div {
    width:100%;
    height:100%;
    overflow:auto;
}

overflow:auto on that container div within the cell does the trick for me. Without it the div does not use the entire height.


R
Radu Simionescu

To make height:100% work for the inner div, you have to set a height for the parent td. For my particular case it worked using height:100%. This made the inner div height stretch, while the other elements of the table didn't allow the td to become too big. You can of course use other values than 100%

If you want to also make the table cell have a fixed height so that it does not get bigger based on content (to make the inner div scroll or hide overflow), that is when you have no choice but do some js tricks. The parent td will need to have the height specified in a non relative unit (not %). And you will most probably have no choice but to calculate that height using js. This would also need the table-layout:fixed style set for the table element


K
Kidd Cudi

I encounter similar issues frequently and always just use table-layout: fixed; on the table element and height: 100%; on the inner div.


P
Peter B

I ultimately found nothing that would work across all my browsers and all DocTypes / browser rendering modes, except for using jQuery. So here is what I came up with. It even takes rowspan into account.

function InitDivHeights() {
    var spacing = 10; // <-- Tune this value to match your tr/td spacing and padding.
    var rows = $('#MyTable tr');
    var heights = [];
    for (var i = 0; i < rows.length; i++)
        heights[i] = $(rows[i]).height();
    for (var i = 0; i < rows.length; i++) {
        var row = $(rows[i]);
        var cells = $('td', row);
        for (var j = 0; j < cells.length; j++) {
            var cell = $(cells[j]);
            var rowspan = cell.attr('rowspan') || 1;
            var newHeight = 0;
            for (var k = 0; (k < rowspan && i + k < heights.length); k++)
                newHeight += heights[i + k];
            $('div', cell).height(newHeight - spacing);
        }
    }
}
$(document).ready(InitDivHeights);

Tested in IE11 (Edge mode), FF42, Chrome44+. Not tested with nested tables.


well, now this is easy with flexbox. this is an old question!
@Jason thanks, but we needed it to work in IE10/IE11 as well, which both have partial / buggy flexbox support according to caniuse.com/#feat=flexbox and also github.com/philipwalton/flexbugs. Maybe later...
M
Muho

you can do it like that:

<td>
  <div style="width: 100%; position: relative; float: left;">inner div</div>
</td>

D
Desolator

a bit late to the party but here's my solution:

<td style="padding: 0; position: relative;">
   <div style="width: 100%; height: 100%; position: absolute; overflow: auto;">
     AaaaaaaaaaaaaaaaaaBBBBBBBbbbbbbbCCCCCCCCCccccc<br>
     DDDDDDDddddEEEEEEEEdddfffffffffgggggggggggggggggggg
   </div>
</td>

n
niffler

If the positioned element and its father element do not have width and height, then set

padding: 0;

in its father element,


u
user1911283

This is probably not recommended.

I figured out a workaround which works if your div doesn't contain text and has an uniform background.

display: 'list-item'

gives the div the desired height and width, but with the big downside of having a list item bullet. Since the div has a homogeneous background-color I got rid of the bullet with those styles:

list-style-position: 'inside',
color: *background-color*,

S
Saadat

If the table cell is the size that you want, just add this css class and assign it to your div:

.block {
   height: -webkit-calc(100vh);
   height: -moz-calc(100vh);
   height: calc(100vh);
   width: 100%;
}

If you want the table cell to fill up the parent too, assign the class to the table cell too.


J
Jeffrey

I'm not sure what you want to do but you might try this one:

<td width="661" valign="top"><div>Content for New Div Tag Goes Here</div></td>


J
Jason

The following should work. You have to set a height to the parent cell. https://jsfiddle.net/nrvd3vgd/

<table style="width:200px; border: 1px solid #000;">
    <tr>
        <td style="height:100px;"></td>
    </tr>
    <tr>
        <td style="height:200px;">
            <div style="height:100%; background: #f00;"></div>
        </td>
    </tr>
</table>

J
JayB

Try this:

<td style="position:relative;">
    <div style="position:absolute;top:0;bottom:0;width:100%;"></div>
</td>

M
Michael Sparks

I think that the best solution would be to use JavaScript.

But I'm not sure that you need to do this to solve your problem of positioning elements in the <td> outside of the cell. For that you could do something like this:

<div style="position:relative">
    <table>
        <tr>
            <td>
                <div style="position:absolute;bottom:-100px">hello world</div>
            </td>
        </tr>
    </table>
</div>

Not inline of course, but with classes and ids.


Thanks for the response. This works if I need to place something relative to the table. I need to place something outside an individual cell where the cell's location is unknown.
can you expand on what this table contains? and what the 100% width/height thing is?
L
Leon Rom

I does not watch here an old CSS-trick for

inside . Hence I remind: simple set some minimal value for width, but what-you-need for min-width. For example:

<div style="width: 3px; min-width: 99%;">

The td's width, in that case, is up to you.


a
akjoshi

This is my Solution for extend 100% height and 100% width in a html <td>

if you delete the first line in your code you can fix it ...

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

because this doctype does not permit in some files to use the 100% percent inside of <td>, but if you delete this line, the body fails expanding the background to 100% height and 100% width, so I found this DOCTYPE that solves the problem

<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">

this DOCTYPE let you extends the background in your body as 100% height and 100% width, and let you take all the 100% height and 100% width into the <td>


Better not to mess with the doctype. You don't seem to be aware of all the consequences. Changing Doctypes can have a lot of side effects (so does most things in CSS world, deplorably).