如何在html表格上显示滚动条
Posted
技术标签:
【中文标题】如何在html表格上显示滚动条【英文标题】:How to display scroll bar onto a html table 【发布时间】:2012-01-04 04:27:24 【问题描述】:我正在编写一个页面,我需要一个 html 表格来保持设定的大小。我需要表格顶部的标题始终保持在那里,但无论向表格中添加多少行,我还需要表格的主体滚动。
我希望它看起来像这个网址中的方法 2:http://www.cssplay.co.uk/menu/tablescroll.html
我试过这样做,但没有出现滚动条:
tbody
height: 80em;
overflow: scroll;
<table border=1 id="qandatbl" align="center">
<tr>
<th class="col1">Question No</th>
<th class="col2">Option Type</th>
<th class="col1">Duration</th>
</tr>
<tbody>
<tr>
<td class='qid'></td>
<td class="options"></td>
<td class="duration"></td>
</tr>
</tbody>
</table>
【问题讨论】:
为什么不使用示例方法中的代码?很遗憾,你不能使用<tbody>
。
【参考方案1】:
这样的?
http://jsfiddle.net/TweNm/
我们的想法是将<table>
包装在一个非静态定位的<div>
中,该<div>
具有overflow:auto
CSS 属性。然后绝对定位<thead>
中的元素。
#table-wrapper
position:relative;
#table-scroll
height:150px;
overflow:auto;
margin-top:20px;
#table-wrapper table
width:100%;
#table-wrapper table *
background:yellow;
color:black;
#table-wrapper table thead th .text
position:absolute;
top:-20px;
z-index:2;
height:20px;
width:35%;
border:1px solid red;
<div id="table-wrapper">
<div id="table-scroll">
<table>
<thead>
<tr>
<th><span class="text">A</span></th>
<th><span class="text">B</span></th>
<th><span class="text">C</span></th>
</tr>
</thead>
<tbody>
<tr> <td>1, 0</td> <td>2, 0</td> <td>3, 0</td> </tr>
<tr> <td>1, 1</td> <td>2, 1</td> <td>3, 1</td> </tr>
<tr> <td>1, 2</td> <td>2, 2</td> <td>3, 2</td> </tr>
<tr> <td>1, 3</td> <td>2, 3</td> <td>3, 3</td> </tr>
<tr> <td>1, 4</td> <td>2, 4</td> <td>3, 4</td> </tr>
<tr> <td>1, 5</td> <td>2, 5</td> <td>3, 5</td> </tr>
<tr> <td>1, 6</td> <td>2, 6</td> <td>3, 6</td> </tr>
<tr> <td>1, 7</td> <td>2, 7</td> <td>3, 7</td> </tr>
<tr> <td>1, 8</td> <td>2, 8</td> <td>3, 8</td> </tr>
<tr> <td>1, 9</td> <td>2, 9</td> <td>3, 9</td> </tr>
<tr> <td>1, 10</td> <td>2, 10</td> <td>3, 10</td> </tr>
<!-- etc... -->
<tr> <td>1, 99</td> <td>2, 99</td> <td>3, 99</td> </tr>
</tbody>
</table>
</div>
</div>
【讨论】:
没有固定宽度的列怎么样? 我尝试了您的答案,但标题列未对齐。我只在 body 标记内的样式标记中使用了你的 CSS,我在其中复制了你的表格 很好的解决方案,但我遇到了问题。当尝试隐藏一行并设置 display:none 时,行之间有一些空格。常规表不是这种情况。有什么想法、提示或建议吗? @Antonio:我遇到了同样的问题(居中*标题列似乎未对齐),但添加transform: translateX(-50%)
对我有用 [*centered 是 Firefox 中的标准样式,已被此答案的 JSFiddle 中的“规范化 CSS”选项]【参考方案2】:
您必须将<table>
插入到具有固定大小的<div>
中,并且在<div>
样式中您必须设置overflow: scroll
。
更新:
最初的答案是 10 年前写的。现在有很多很好的用于表格视图的 UI 组件并以适当的方式显示。因此,我的建议是选择这些免费或付费组件之一,以确保您已经支持许多已经在这些组件中实现的边缘案例。
【讨论】:
为我的 div 设置了 500px 的高度,它工作得很好。 不知道为什么每个人都把它弄得这么复杂。这应该是公认的答案。 这是迄今为止最简单的解决方案。添加具有溢出和固定高度的 div 可能有一些注意事项,但此解决方案至少会让您朝着正确的方向前进。 精湛的答案队友!为你干杯:)- 这应该是公认的答案。简单,直截了当,我不会用它破坏任何其他东西。【参考方案3】:接受的答案提供了一个很好的起点,但如果您调整框架大小、更改列宽,甚至更改表格数据,标题将以各种方式弄乱。我见过的所有其他示例都有类似的问题,或者对表格的布局施加了一些严重的限制。
不过,我想我终于解决了所有这些问题。它使用了 很多 CSS,但最终产品与普通表格一样可靠且易于使用。
这是一个示例,它具有复制 OP 引用的表所需的所有功能:jsFiddle
必须更改颜色和边框以使其与参考相同。 CSS cmets 中提供了有关如何进行此类更改的信息。
代码如下:
/*the following html and body rule sets are required only if using a % width or height*/
/*html
width: 100%;
height: 100%;
*/
body
box-sizing: border-box;
width: 100%;
height: 100%;
margin: 0;
padding: 0 20px 0 20px;
text-align: center;
background: white;
.scrollingtable
box-sizing: border-box;
display: inline-block;
vertical-align: middle;
overflow: hidden;
width: auto; /*if you want a fixed width, set it here, else set to auto*/
min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/
height: 188px/*100%*/; /*set table height here; can be fixed value or %*/
min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
font-family: Verdana, Tahoma, sans-serif;
font-size: 15px;
line-height: 20px;
padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
text-align: left;
.scrollingtable * box-sizing: border-box;
.scrollingtable > div
position: relative;
border-top: 1px solid black;
height: 100%;
padding-top: 20px; /*this determines column header height*/
.scrollingtable > div:before
top: 0;
background: cornflowerblue; /*header row background color*/
.scrollingtable > div:before,
.scrollingtable > div > div:after
content: "";
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
left: 0;
.scrollingtable > div > div
min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/
max-height: 100%;
overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/
overflow-x: hidden;
border: 1px solid black; /*border around table body*/
.scrollingtable > div > div:after background: white; /*match page background color*/
.scrollingtable > div > div > table
width: 100%;
border-spacing: 0;
margin-top: -20px; /*inverse of column header height*/
/*margin-right: 17px;*/ /*uncomment if using % width*/
.scrollingtable > div > div > table > caption
position: absolute;
top: -20px; /*inverse of caption height*/
margin-top: -1px; /*inverse of border-width*/
width: 100%;
font-weight: bold;
text-align: center;
.scrollingtable > div > div > table > * > tr > * padding: 0;
.scrollingtable > div > div > table > thead
vertical-align: bottom;
white-space: nowrap;
text-align: center;
.scrollingtable > div > div > table > thead > tr > * > div
display: inline-block;
padding: 0 6px 0 6px; /*header cell padding*/
.scrollingtable > div > div > table > thead > tr > :first-child:before
content: "";
position: absolute;
top: 0;
left: 0;
height: 20px; /*match column header height*/
border-left: 1px solid black; /*leftmost header border*/
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before
position: absolute;
top: 0;
white-space: pre-wrap;
color: white; /*header row font color*/
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after content: attr(label);
.scrollingtable > div > div > table > thead > tr > * + :before
content: "";
display: block;
min-height: 20px; /*match column header height*/
padding-top: 1px;
border-left: 1px solid black; /*borders between header cells*/
.scrollingtable .scrollbarhead float: right;
.scrollingtable .scrollbarhead:before
position: absolute;
width: 100px;
top: -1px; /*inverse border-width*/
background: white; /*match page background color*/
.scrollingtable > div > div > table > tbody > tr:after
content: "";
display: table-cell;
position: relative;
padding: 0;
border-top: 1px solid black;
top: -1px; /*inverse of border width*/
.scrollingtable > div > div > table > tbody vertical-align: top;
.scrollingtable > div > div > table > tbody > tr background: white;
.scrollingtable > div > div > table > tbody > tr > *
border-bottom: 1px solid black;
padding: 0 6px 0 6px;
height: 20px; /*match column header height*/
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * border-bottom: none;
.scrollingtable > div > div > table > tbody > tr:nth-child(even) background: gainsboro; /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * border-left: 1px solid black; /*borders between body cells*/
<div class="scrollingtable">
<div>
<div>
<table>
<caption>Top Caption</caption>
<thead>
<tr>
<th><div label="Column 1"></div></th>
<th><div label="Column 2"></div></th>
<th><div label="Column 3"></div></th>
<th>
<!--more versatile way of doing column label; requires 2 identical copies of label-->
<div><div>Column 4</div><div>Column 4</div></div>
</th>
<th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
</tr>
</thead>
<tbody>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
</tbody>
</table>
</div>
Faux bottom caption
</div>
</div>
<!--[if lte IE 9]><style>.scrollingtable > div > div > table margin-right: 17px;</style><![endif]-->
【讨论】:
很棒的工作。但是,我有一个包含 15 列的表格,现在我似乎也无法在没有水平滚动条的情况下将表格包含在页面中。我已经尝试调整你的 css,你编码精美的 css,以适应更多动态宽度的列,但除了表格宽度之外,我没有改变任何东西。如果我将表格宽度更改为 100%,那么表格将呈现在表格的宽度中,但由于列宽不会换行,我仍然看不到所有 15 列数据。我几乎有一个看起来很酷的滚动表,所以任何帮助表示赞赏。 哦,等一下,没有水平滚动条,表格就被切断了。 @nanker 如果你需要水平滚动并且愿意使用一点点 javascript,你应该检查this answer。这是我知道的做滚动表的最佳方式。当我发布这个答案时,没有很好的方法可以只使用 CSS 进行水平滚动,但我有一段时间没有研究它,所以我不知道现在有什么可能。 很棒的工作。您能否评论如何调整多个标题行?简单地重复<tr><th></th>..</tr>
结构显然是行不通的。谢谢。
@DavidI.McIntosh 使用这种技术多行标题会很棘手。添加行很容易,但我不确定如何获得它们之间的水平边界。您可能想尝试我在之前评论中链接的 JavaScript 解决方案,除非由于某种原因您不能使用 JS。【参考方案4】:
不知道为什么没有人提到只对元素使用内置的粘性标题样式。对我来说效果很好。
.tableContainerDiv
overflow: auto;
max-height: 80em;
th
position: sticky;
top: 0;
background: white;
如果您需要做出响应(或类似),请在@media 中设置最小宽度。
见Table headers position:sticky或Position Sticky and Table Headers
【讨论】:
这是一种更简洁的方法,更接近原始表格,并且使用最少的 css。其他答案已过时。【参考方案5】:我通过将我的内容分成两个表格解决了这个问题。
一个表是标题行。
秒也是<table>
标签,但被<div>
包裹,具有静态高度和溢出滚动。
【讨论】:
【参考方案6】:值得注意的是,根据您的目的(我的目的是搜索栏的自动填充结果),您可能希望高度是可变的,并且滚动条仅在高度超过该高度时才存在。
如果需要,请将height: x;
替换为max-height: x;
,将overflow:scroll
替换为overflow:auto
。
此外,如果需要,您可以使用overflow-x
和overflow-y
,显然同样的事情与width : x;
水平工作
【讨论】:
【参考方案7】:非常简单,只需将表格包裹在具有overflow-y:scroll;
和overflow-x:scroll
属性的div 中,并使div 的宽度和长度小于表格。
它会工作的!!!
【讨论】:
好的,我会在下一个答案中添加。 好的,做到了,我还不知道如何在堆栈溢出时正确缩进代码。【参考方案8】:如果您遇到所有提到的解决方案都不起作用的地步(就像我遇到的那样),请执行以下操作:
创建两个表。一个用于标题,另一个用于正文 给两个表不同的父容器/div 设置第二个表格的 div 以允许垂直滚动其内容。像这样,在你的HTML
<div class="table-header-class">
<table>
<thead>
<tr>
<th>Ava</th>
<th>Alexis</th>
<th>Mcclure</th>
</tr>
</thead>
</table>
</div>
<div class="table-content-class">
<table>
<tbody>
<tr>
<td>I am the boss</td>
<td>No, da-da is not the boss!</td>
<td>Alexis, I am the boss, right?</td>
</tr>
</tbody>
</table>
</div>
然后在您的CSS
中设置第二个表的父级以允许垂直滚动
.table-content-class
overflow-y: scroll; // use auto; or scroll; to allow vertical scrolling;
overflow-x: hidden; // disable horizontal scroll
【讨论】:
这与 Zvi 一年前的回答相同。【参考方案9】:添加到表格中
style="overflow-x:auto;"
<table border=1 id="qandatbl" align="center" style="overflow-x:auto;">
<tr>
<th class="col1">Question No</th>
<th class="col2">Option Type</th>
<th class="col1">Duration</th>
</tr>
<tbody>
<tr>
<td class='qid'></td>
<td class="options"></td>
<td class="duration"></td>
</tr>
</tbody>
</table>
style="overflow-x:auto;"`
【讨论】:
问题是如何在列标题保持不变的情况下使表格主体垂直滚动。【参考方案10】:CSS:
div overflow-y:scroll; overflow-x:scroll; width:20px; height:30px; table width:50px; height:50px;
你可以把桌子和桌子周围的 DIV 做成你想要的任何大小,只要确保 DIV 比桌子小。 您必须将表格包含在 DIV 中。
【讨论】:
以上是关于如何在html表格上显示滚动条的主要内容,如果未能解决你的问题,请参考以下文章
html表格table的宽度超出页面宽度时如何不改变table宽度(只显示出滚动条)?