跨浏览器 css 问题,其中 height:100% 不会被表中的子元素继承



我从 2005 年左右继承了一个 Web 应用程序,其中包含许多表格样式,请参阅 https://jsfiddle.net/6t7r1fma

<table style="height:50px">
<tr style="height:100%">
<td style="height:100%">
<div style="overflow-y:scroll;height:100%">
<table style="table-layout:fixed">
<tr>
<td>One</td>
<td>Two</td>
</tr>
<tr>
<td>Three</td>
<td>Four</td>
</tr>
<tr>
<td>Five</td>
<td>Six</td>
</tr>
<tr>
<td>Seven</td>
<td>Eight</td>
</tr>
<tr>
<td>Nine</td>
<td>Ten</td>
</tr>
<tr>
<td>Eleven</td>
<td>Twelve</td>
</tr>
</table>
</div>
</td>
</tr>
</table>

问题是我希望内部表尽可能大,但包含在可以垂直滚动的溢出div 中。 它适用于Chrome,但不适用于Firefox(不太重要)和IE(更重要)。 发生的情况是溢出div 采用子表而不是父表的高度,结果是完整显示内部表。

有什么想法吗? 重写HTML并不是一个真正的选择,所以希望有一个CSS解决方案。

不幸的是,表格的工作方式可以总结为:它们围绕内容调整自己的大小。 您唯一的解决方案是将max-height从外部表传递到其单元格内的<div>上。

如果您希望动态执行此操作,而不更改标记(这将是正确的方法),则可以:

  • 使用CSS完全隐藏表格的内容,并让单元格获得正常大小
  • 在页面加载时(将表添加到DOM并呈现后),获取父<table>的高度,并将其作为max-height放置在<td>中包含的<div>上。当然,这只能在javascript中完成。

除此之外,您唯一的其他选择是直接将max-height放在td内的div上(这就是下面的解决方案使用javascript所做的)。

注意,我添加了一个关于一般原则的id,以包含它,但只要你知道你在做什么,并且这不会影响其他任何事情,你真的不需要它。概念验证:

var divs = document.querySelectorAll('#fix>tbody>tr>td>div');
[].forEach.call(divs, function(div){
div.style.maxHeight = div.parentNode.clientHeight + 'px';
div.style.display = 'block';
})
#fix>tbody>tr>td>div {display: none;}
<table style="height:50px" id="fix" cellpadding="0" cellspacing="0">
<tr style="height:100%">
<td style="height:100%">
<div style="overflow-y:scroll;height:100%">
<table style="table-layout:fixed">
<tr>
<td>One</td>
<td>Two</td>
</tr>
<tr>
<td>Three</td>
<td>Four</td>
</tr>
<tr>
<td>Five</td>
<td>Six</td>
</tr>
<tr>
<td>Seven</td>
<td>Eight</td>
</tr>
<tr>
<td>Nine</td>
<td>Ten</td>
</tr>
<tr>
<td>Eleven</td>
<td>Twelve</td>
</tr>
</table>
</div>
</td>
</tr>
</table>


如果您已经在项目中加载jQuery,则可能应该使用它(尚未测试,但它应包含IE8,而上述内容没有):

$('#fix>tbody>tr>td>div').each(function(){
$(this).css({
"max-height":$(this).parent().height() + 'px',
display:"block"
});
})
#fix>tbody>tr>td>div {display: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="height:50px" id="fix" cellpadding="0" cellspacing="0">
<tr style="height:100%">
<td style="height:100%">
<div style="overflow-y:scroll;height:100%">
<table style="table-layout:fixed">
<tr>
<td>One</td>
<td>Two</td>
</tr>
<tr>
<td>Three</td>
<td>Four</td>
</tr>
<tr>
<td>Five</td>
<td>Six</td>
</tr>
<tr>
<td>Seven</td>
<td>Eight</td>
</tr>
<tr>
<td>Nine</td>
<td>Ten</td>
</tr>
<tr>
<td>Eleven</td>
<td>Twelve</td>
</tr>
</table>
</div>
</td>
</tr>
</table>


请注意,由于用户代理的默认样式,表格元素可能会在不同的浏览器中呈现,间距较小(单元格填充和单元格间距)(通常为 1-2px),这些元素将从可用高度中扣除。您可以通过在父<table>上将cellpaddingcellspacing设置为 0(就像我所做的那样)或通过重置<table>元素的用户代理默认样式来防止此行为。

您可以将显示块添加到父表及其表正文、表行和表单元格吗?这适用于 Firefox 和 IE 11(不确定您必须追溯多远)。

https://jsfiddle.net/fwuzqo3o/

<table style="height:50px; display: block;">
<tbody style="height: 100%; display: block;">
<tr style="height:100%; display: block;">
<td style="height:100%; display: block;">
<div style="overflow-y:scroll;height:100%">
<table style="table-layout:fixed">
<tr>
<td>One</td>
<td>Two</td>
</tr>
<tr>
<td>Three</td>
<td>Four</td>
</tr>
<tr>
<td>Five</td>
<td>Six</td>
</tr>
<tr>
<td>Seven</td>
<td>Eight</td>
</tr>
<tr>
<td>Nine</td>
<td>Ten</td>
</tr>
<tr>
<td>Eleven</td>
<td>Twelve</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>

最新更新