如何在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>

【问题讨论】:

为什么不使用示例方法中的代码?很遗憾,你不能使用&lt;tbody&gt; 【参考方案1】:

这样的?

http://jsfiddle.net/TweNm/

我们的想法是将&lt;table&gt; 包装在一个非静态定位的&lt;div&gt; 中,该&lt;div&gt; 具有overflow:auto CSS 属性。然后绝对定位&lt;thead&gt;中的元素。

#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】:

您必须将&lt;table&gt; 插入到具有固定大小的&lt;div&gt; 中,并且在&lt;div&gt; 样式中您必须设置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 进行水平滚动,但我有一段时间没有研究它,所以我不知道现在有什么可能。 很棒的工作。您能否评论如何调整多个标题行?简单地重复 &lt;tr&gt;&lt;th&gt;&lt;/th&gt;..&lt;/tr&gt; 结构显然是行不通的。谢谢。 @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】:

我通过将我的内容分成两个表格解决了这个问题。

一个表是标题行。

秒也是&lt;table&gt;标签,但被&lt;div&gt;包裹,具有静态高度和溢出滚动。

【讨论】:

【参考方案6】:

值得注意的是,根据您的目的(我的目的是搜索栏的自动填充结果),您可能希望高度是可变的,并且滚动条仅在高度超过该高度时才存在。

如果需要,请将height: x; 替换为max-height: x;,将overflow:scroll 替换为overflow:auto

此外,如果需要,您可以使用overflow-xoverflow-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宽度(只显示出滚动条)?

延伸到屏幕外的 HTML 表格

向 HTML 表格添加水平滚动条

如图,怎么在html表格中内容超出时自动显示滚动条,求代码,。

如何让bootstrap表格自动出现水平滚动条

如何设定html table 过宽下方出现滚动条