带有固定页眉和页脚的 HTML 表格以及没有固定宽度的可滚动正文 [英] HTML table with fixed header and footer and scrollable body without fixed widths
问题描述
我想用固定的 thead
和 tfoot
和一个可滚动的 tbody
创建一个表格!
我尝试了几种方法,包括仅 CSS 和 CSS + Javascript,但它们都很弱且不可靠,我可以通过更改演示中的标记轻松破坏它们.
我想要的是一种让表格表现得像表格的方法,这意味着浏览器将根据内容自动调整列(都在页面在调整窗口大小的情况下加载)以及在这些情况下:
如果列标题的内容 (
thead > tr > th
) 大于列正文的内容 (tbody > tr > td
) 并且大于列页脚的内容 (tfoot > tr > td
) 列应根据列标题的大小调整大小如果列正文的内容 (
tbody > tr > td
) 大于列标题的内容 (thead > tr > th
) 并且大于列页脚的内容 (tfoot > tr > td
) 列应根据列正文的大小调整大小如果列的页脚内容 (
tfoot > tr > td
) 大于列标题的内容 (thead > tr > th
) 并且大于列正文的内容 (tbody > tr > td
) 列应根据列页脚的大小调整大小
下面的table
应该阐明场景:
<头><tr><th>标题一*领先宽度*(情况1)</th><th>标题二</th><th>标题三</th></tr></thead><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr></tbody><脚><tr><td>页脚一</td><td>页脚二</td><td>页脚三*领先宽度*(情况3)</td></tr></tfoot>
我想要一个干净(尽可能)和可靠的解决方案,它适用于不同的场景,可能只有 CSS,但 JavaScript 也可以(普通和干净的 JavaScript,而不是 jQuery 插件).我不关心旧浏览器的支持(拥有它或至少达到可以在旧浏览器上优雅降级的解决方案,但它是可选的)......我什至可以接受使用 div如果最终解决方案按预期工作,则代码>s 而不是表节点......所以在 2016 年,使用现代浏览器和 CSS 是否有可能以某种方式实现?!
正文应该垂直滚动,表格可以有任意数量的列
更新:
我想出了这个解决方案:https://codepen.io/daveoncode/pen/LNomBE一>但我仍然不是 100% 满意.主要问题是我无法为页眉和页脚单元格设置不同的背景.
更新 2:
现在可以使用了!
我终于实现了一个可行的解决方案!
相关的 CSS 如下:
.wrapper {宽度:90%;位置:相对;边框:1px 实心 #000;背景:#efefef;溢出:隐藏;边框半径:7px;}.容器 {溢出-y:自动;高度:200px;边框顶部:41px 实心透明;边框底部:41px 实心透明;}桌子 {边框间距:0;边框折叠:折叠;宽度:100%;}td + td {左边框:1px 实心 #fff;}td, th {边框底部:1px 实心 #fff;背景:#efefef;填充:10px;}头 tr th,tfoot tr td {高度:0;行高:0;边距:0;填充顶部:0;填充底部:0;颜色:透明;边界:无;空白:nowrap;}thead tr th div,tfoot tr td div {位置:绝对;颜色:#fff;高度:20px;填充:10px;左边距:-10px;行高:正常;宽度:100%;z-索引:2;文本对齐:左;字体粗细:粗体;}thead tr th div {左边框:1px 实心 #000;边框底部:1px 实心 #000;}tfoot tr td div {边框顶部:1px 实心 #000;}tfoot tr td div.c1,thead tr th div.c1 {背景:紫罗兰;}tfoot tr td div.c2,thead tr th div.c2 {背景:绿色;}tfoot tr td div.c3,thead tr th div.c3 {背景:黄色;}thead tr th div {顶部:0;}tfoot tr td div {底部:0;}thead tr th:first-child div,tfoot tr td:first-child div {左边界:无;}
这是标记:
<div class="容器"><表格><头><tr><th>表头一*领先宽度*(情况1)<div class="c1">表头一*领先宽度*(情况1)</th><th>标题二<div class="c2">标题二
</th><th>标题三<div class="c3">标题三
</th></tr></thead>
<tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列[第一]</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列</td></tr><tr><td>第一列</td><td>第二列*领先宽度*(情况2)</td><td>第三列[最新]</td></tr></tbody><脚><tr><td>页脚一<div class="c1">页脚一</td><td>页脚二<div class="c2">页脚二</div></td><td>页脚三*领先宽度*(情况3)<div class="c3">页脚三*领先宽度*(情况3)</div></td></tr></tfoot>
它适用于 Chrome、Firefox、Safari 和 IE11(我不知道它在旧浏览器上的表现如何).在 codepen 上查看:https://codepen.io/daveoncode/pen/LNomBE
I want to to create a table with fixed thead
and tfoot
and a scrollable tbody
!
I've tried several approaches, both CSS only and CSS + Javascript, but they are all weak and unreliable and I can easily break them by changing the markup in the demo.
What I want is a way to have the table to behave like a table, this means that the browser will automatically adjust columns based on the content (both at page load that in case of window resize) and that in these scenarios:
if the content of the column's header (
thead > tr > th
) is larger than the content of the column's body (tbody > tr > td
) and larger than the content of the column's footer (tfoot > tr > td
) the column should resize based on the size of the column's headerif the content of the column's body (
tbody > tr > td
) is larger than the content of the column's header (thead > tr > th
) and larger than the content of the column's footer (tfoot > tr > td
) the column should resize based on the size of the column's bodyif the content of the column's footer (
tfoot > tr > td
) is larger than the content of the column's header (thead > tr > th
) and larger than the content of the column's body (tbody > tr > td
) the column should resize based on the size of the column's footer
The table
below should clarify the scenarios:
<table>
<thead>
<tr>
<th>Header one *leads the width* (case 1)</th>
<th>Header two</th>
<th>Header three</th>
</tr>
</thead>
<tbody>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer one</td>
<td>Footer two</td>
<td>Footer three *leads the width* (case 3)</td>
</tr>
</tfoot>
</table>
I want a clean (as possible) and reliable solution that will work for the different scenarios, possibly CSS only but also JavaScript is OK (vanilla and clean JavaScript, not jQuery plugins).
I don't care about old browser support (it would be great to have it or at least to reach a solution which can degrade gracefully on old browser but it's optional)... I can even accept to use div
s instead of table nodes if the final solution works as expected... so in 2016, with modern browser and CSS is this possible somehow?!
EDIT:
The body should scroll vertically and the table may have any number of columns
UPDATE:
I came up with this solution: https://codepen.io/daveoncode/pen/LNomBE but I'm still not 100% satisfied. The main issue is that I can't set different backgrounds for header and footer cells.
UPDATE 2:
it works now!
I finally implemented a working solution!
The relevant CSS is the following:
.wrapper {
width: 90%;
position: relative;
border: 1px solid #000;
background: #efefef;
overflow: hidden;
border-radius: 7px;
}
.container {
overflow-y: auto;
height: 200px;
border-top: 41px solid transparent;
border-bottom: 41px solid transparent;
}
table {
border-spacing: 0;
border-collapse: collapse;
width: 100%;
}
td + td {
border-left: 1px solid #fff;
}
td, th {
border-bottom: 1px solid #fff;
background: #efefef;
padding: 10px;
}
thead tr th,
tfoot tr td {
height: 0;
line-height: 0;
margin: 0;
padding-top: 0;
padding-bottom: 0;
color: transparent;
border: none;
white-space: nowrap;
}
thead tr th div,
tfoot tr td div {
position: absolute;
color: #fff;
height: 20px;
padding: 10px;
margin-left: -10px;
line-height: normal;
width: 100%;
z-index: 2;
text-align: left;
font-weight: bold;
}
thead tr th div {
border-left: 1px solid #000;
border-bottom: 1px solid #000;
}
tfoot tr td div {
border-top: 1px solid #000;
}
tfoot tr td div.c1,
thead tr th div.c1 {
background: violet;
}
tfoot tr td div.c2,
thead tr th div.c2 {
background: green;
}
tfoot tr td div.c3,
thead tr th div.c3 {
background: yellow;
}
thead tr th div {
top: 0;
}
tfoot tr td div {
bottom: 0;
}
thead tr th:first-child div,
tfoot tr td:first-child div {
border-left: none;
}
And this is the markup:
<div class="wrapper">
<div class="container">
<table>
<thead>
<tr>
<th>
Header one *leads the width* (case 1)
<div class="c1">
Header one *leads the width* (case 1)
</div>
</th>
<th>
Header two
<div class="c2">
Header two
</div>
</th>
<th>
Header three
<div class="c3">
Header three
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three [first]</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three</td>
</tr>
<tr>
<td>Column one</td>
<td>Column two *leads the width* (case 2)</td>
<td>Column three [LATEST]</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
Footer one
<div class="c1">
Footer one
</div>
</td>
<td>
Footer two
<div class="c2">Footer two</div>
</td>
<td>
Footer three *leads the width* (case 3)
<div class="c3">Footer three *leads the width* (case 3)</div>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
It works on Chrome, Firefox, Safari and IE11 (I don't know how it behaves on older browsers). See it on codepen: https://codepen.io/daveoncode/pen/LNomBE
这篇关于带有固定页眉和页脚的 HTML 表格以及没有固定宽度的可滚动正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!