如何让一个div填满整个表格单元格?

14

我试图将一个div元素填充到表格的中心单元格。为了说明问题,这个div被设置了红色背景样式。它在Chrome中似乎可以正常工作,但在IE中无法正常显示。在下面的示例中,IE将div元素的高度设置为刚好包含其内容所需的最小高度。在使用不同的CSS设置尝试解决此问题时,我成功地让IE将“height:100%”解释为“浏览器窗口的高度”。然而,如问题所述,我希望IE将其解释为td单元格的高度。有什么想法吗?

http://jsfiddle.net/UBk79/

CSS:

*{
    padding: 0px;
    margin: 0px;
}
html, body{
    height: 100%;
}
#container{
    height:100%;
    width: 100%;
    border-collapse:collapse;
}
#centerCell{
    border: 1px solid black;
}
#main{
    height: 100%;
    background-color: red;
}

HTML:

<table id="container">
  <tr id="topRow" height="1px">
    <td id="headerCell" colspan="3">
      TOP
    </td>
  </tr>
  <tr id="middleRow">
    <td id="leftCell" width="1px">
      LEFT
    </td>
    <td id="centerCell">
      <div id="main">CENTER</div>
    </td>
    <td id="rightCell" width="1px">
      RIGHT
    </td>
  </tr>
  <tr id="bottomRow" height="1px">
    <td id="footerCell" colspan="3">
      BOTTOM
    </td>
  </tr>
</table>

你是否在使用表格来布置网页? - cronoklee
是的。昨天我花了一整天的时间试图发明/找到一个CSS解决方案来实现上述目标。我找到的最接近的东西是回答不同的StackOverflow问题:https://dev59.com/9XRB5IYBdhLWcg3wv5o_#19110204 正如你所看到的,它使用CSS表格显示属性,但当您尝试让一些“单元格”跨越多个“列”时,它会崩溃,因为显然没有CSS类似于colspan属性的东西。 - Craig
我找到或想到的其它 CSS 解决方案要么(a)需要指定页脚的高度,要么(b)当内容短于窗口高度时无法将页脚保持在窗口底部,要么(c)当内容高于窗口高度时有重叠现象,要么(d)需要浏览器渲染部分或全部 DOM,然后运行一些 JavaScript,再重新渲染页面。在 Chrome 中,表格布局是我找到的第一个没有以上问题的解决方案。但在 IE 中好像无法正常工作... - Craig
2018年更新:看起来现在在Chrome、Firefox、IE11和Edge中都可以工作了。(Firefox需要添加@cloudpta建议的“height: 100%;”)我猜IE在某个时候改变了其算法以匹配其他浏览器。我还没有测试旧版本的IE,以确定这个变化发生的确切时间。 - Craig
6个回答

24

我对此进行了更多的研究并收集了一些信息,这可能对其他试图解决类似问题的人有所帮助。CSS规范指出了以下三点,我认为它们很重要:

首先,关于将高度(div的高度)指定为百分比:

百分比是相对于生成框的包含块的高度计算的。如果未明确指定包含块的高度(即依赖于内容高度),并且此元素未绝对定位,则该值计算为“auto”。

http://www.w3.org/TR/CSS21/visudet.html#the-height-property

... 'auto'的高度只有在内容高度大于单元格的最小高度时才会填充单元格。但是,如果我们尝试显式设置包含单元格或行的高度,那么就会遇到以下问题:

CSS 2.1没有定义使用百分比值指定表格单元格和表格行的高度如何计算。

http://www.w3.org/TR/CSS21/tables.html#height-layout

由于规范没有定义它,我想Chrome和IE选择以不同的方式计算它并不令人感到意外。

或者(就像xec间接指出的那样)尝试使用相对定位会有以下规范问题:

相对定位“position:relative”对于table-row-group、table-header-group、table-footer-group、table-row、table-column-group、table-column、table-cell和table-caption元素的效果未定义。

www.w3.org/TR/CSS21/visuren.html#propdef-position

因此,我得出结论在大多数浏览器上可能没有纯CSS的解决方法可以合理地解决这个问题。

一开始,我认为:“哇,CSS规范相当拙劣和不完整,竟然把这些问题都留给未定义状态。” 然而,随着我的思考深入,我意识到,在定义这些问题的规范时,比起一开始看起来要复杂得多。毕竟,行/单元格高度是根据它们的内容高度计算出来的,而我想让我的内容高度成为行/单元格高度的函数。尽管在我的具体情况下,我有一个明确定义、可终止的算法来满足我的需求,但并不清楚这个算法是否能够轻易地推广到其他规范需要涵盖的所有其他情况,而不会陷入无限循环。


2
希望像 flexbox 和/或 css grid 这样的补充功能能够使CSS在布局方面变得更好。如果您分享您的结论,将会得到加分。 - xec
我很难理解将元素的高度设置为其父元素的高度百分比(明确设置或未明确设置)会导致无限循环的原因?有非常清晰的方法可以实现这一点,这绝不是神秘的知识。唯一神秘的知识是为什么CSS规范不支持此功能。 - Slight
如果单元格高度是内容高度的函数,那么您不能使内容高度成为单元格高度的函数。这是循环逻辑。可以在规范中添加一些额外的复杂性来处理这些情况,但正如您所说,有多种方法可以实现它,而且并不明显哪种方法最好,甚至是否存在一种最佳方法来实现它。这会变得混乱。无论如何,我只是猜测为什么它没有被定义。我不是CSS规范委员会的成员。 - Craig

10

只需将表格单元格设置为:position:relative,将 div 设置为:

position:absolute;
top:0;
left:0;
width:100%;
height:100%;

2017年更新: 以下是演示:

请注意,您无法看到红色td,因为黄色div完全覆盖了它...

#expandingDiv {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  background: yellow;
}
<table style="width: 120px">
  <tr>
    <td style="background: blue">blue&nbsp;td</td>
    <td style="background: green">green&nbsp;td</td>
  </tr>
  <tr>
    <td style="background: red; position: relative">
      <div id='expandingDiv'> yellow div </div>
    </td>
    <td style="background: orange">
      Some longer text which makes the bottom two tds expand dynamically.
    </td>
  </tr>
</table>


2
那没有额外的标记是行不通的。阅读更多信息,请访问http://css-tricks.com/absolutely-position-element-within-a-table-cell/。 - xec
2
我已经阅读了那个页面。尽管答案已被接受,但正如Jason在接受的解决方案的第二条评论中指出的那样,它并不正确。缺乏适当的背景颜色是证明所提出的解决方案不起作用的证据。感谢你的尝试。 - Craig
更新的答案,带有一个例子 - cronoklee

2
尽管我喜欢Craig的答案,并且不会自己使用这个答案中的方法,但是我在这个 jsFiddle 上已经取得了很大的进展。
然而,它依赖于一个hack:在表格上设置height: 1px。它在Chrome、FF、IE11和Edge(我测试过的所有浏览器)中都有效,但Chrome在一些极端情况下开始出现问题。请参见该fiddle。以下是有趣的部分:
table {
    width: 100%;
    /* Whý does this make it work? */
    height: 1px;
}

td {
    border: 10px solid blue;
    height: 100%;
}

#container {
    width: calc(100% - 20px);
    height: calc(100% - 20px);
    border: 10px solid black;
}

对我来说有点太刻意了。

1
我认为这个方法是通过将表格(以及其组件)具有明确定义的高度,使得“100%”相对于它。 - SLaks

1

你尝试将CSS更改为以下内容了吗:

#centerCell{
    border: 1px solid black;
    height:100%;
}

在Edge、Firefox和Chrome上似乎对我有效


2018年更新:看起来现在在Chrome、Firefox、IE11和Edge中都可以工作了。(Firefox需要添加@cloudpta建议的“height: 100%;”)我猜IE在某个时候改变了其算法以匹配其他浏览器。我还没有测试旧版本的IE,以确定这个变化发生的确切时间。 - Craig

-1

只需设置 div 的行高即可,只要它的显示仍然是块级元素。不需要相对或绝对定位,也不需要在 div 级别或其任何父级中硬编码高度。适用于 IE 8+、Firefox 和 Chrome。

示例:

line-height: 50px;
// or
line-height: 2em;

-1

这里有一个 jsfiddle:https://jsfiddle.net/55cc077/pvu5cmta/

如果元素的父元素没有显式定义高度,CSS 属性 height: 100% 将不起作用。这段 jQuery 会设置第一列表格单元格的高度。

<script type="text/javascript">
    $(function(){
    $('.myTable2 tr').each(function(){
    var H1 = $(this).height(); // Get the row height
    $(this).find('td:first').css({'height': H1 + 'px', 'line-height': H1 + 'px'}); //Set td height to row height
    });
});
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接