跨浏览器 css 问题 height:100% 不会被 table 中的子元素继承
Cross-browser css issue where height:100% doesn't get inherited by child elements in a table
我从 2005 年左右继承了一个 Web 应用程序,其中有很多 table 样式,请参阅 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>
问题是我希望内部 table 尽可能大,但包含在可以垂直滚动的溢出 div 中。它适用于 Chrome 但不适用于 Firefox(不太重要)和 IE(更重要)。发生的事情是溢出 div 正在占用子 table 而不是父 table 的高度,结果是内部 table 被完整显示.
有什么想法吗?重写 HTML 并不是一个真正的选择,所以希望有一个 CSS 解决方案。
您能否向父级 table 添加一个显示块,它是 table 正文、table 行和 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>
不幸的是,table的工作方式可以总结为:他们围绕内容调整自己的规模。您唯一的解决方案是将 max-height
从外部 table 传递到其单元格内的 <div>
。
如果您更愿意动态地执行此操作,而不更改您的标记(这将是正确的方法),您可以:
- 完全隐藏 table 的内容,使用 CSS 并让单元格变为 正常 大小
- 在页面加载时(在 table 添加到
DOM
并呈现后),获取父级 <table>
的高度并将其作为 max-height
<div>
包含在您的 <td>
中。当然,这只能在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>
请注意,由于用户代理的默认样式,table 元素可能会在不同的浏览器中以较小的间距(cellpadding 和 cellspacing)(通常为 1-2px)呈现,这些元素将从可用高度中扣除。您可以通过在父级 <table>
上将 cellpadding
和 cellspacing
都设置为 0(就像我所做的那样)或通过重置 <table>
元素的用户代理默认样式来防止此行为。
我从 2005 年左右继承了一个 Web 应用程序,其中有很多 table 样式,请参阅 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>
问题是我希望内部 table 尽可能大,但包含在可以垂直滚动的溢出 div 中。它适用于 Chrome 但不适用于 Firefox(不太重要)和 IE(更重要)。发生的事情是溢出 div 正在占用子 table 而不是父 table 的高度,结果是内部 table 被完整显示.
有什么想法吗?重写 HTML 并不是一个真正的选择,所以希望有一个 CSS 解决方案。
您能否向父级 table 添加一个显示块,它是 table 正文、table 行和 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>
不幸的是,table的工作方式可以总结为:他们围绕内容调整自己的规模。您唯一的解决方案是将 max-height
从外部 table 传递到其单元格内的 <div>
。
如果您更愿意动态地执行此操作,而不更改您的标记(这将是正确的方法),您可以:
- 完全隐藏 table 的内容,使用 CSS 并让单元格变为 正常 大小
- 在页面加载时(在 table 添加到
DOM
并呈现后),获取父级<table>
的高度并将其作为max-height
<div>
包含在您的<td>
中。当然,这只能在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>
请注意,由于用户代理的默认样式,table 元素可能会在不同的浏览器中以较小的间距(cellpadding 和 cellspacing)(通常为 1-2px)呈现,这些元素将从可用高度中扣除。您可以通过在父级 <table>
上将 cellpadding
和 cellspacing
都设置为 0(就像我所做的那样)或通过重置 <table>
元素的用户代理默认样式来防止此行为。