如何在HTML表格上显示滚动条


85

我正在写一个页面,我需要一个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>不幸使用。
Mike Park

Answers:


162

像这样吗

http://jsfiddle.net/TweNm/

这个想法是将其包装<table><div>具有overflow:autoCSS属性的非静态位置。然后将元素放置在<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>


15
没有宽度固定的列怎么办?
Fractaliste 2014年

3
我尝试了您的答案,但标题列未对齐。我只在复制表格的body标签内的样式标签中使用了您的css
Antonio

很好的解决方案,但是我遇到了问题。尝试隐藏一行并设置display:none时,行之间会有一些空白。常规表不是这种情况。有任何想法,技巧或建议吗?
Daniil Shevelev '18

@Antonio:我遇到了同样的问题(居中的*标题列似乎不对齐),但是添加transform: translateX(-50%)了对我有用的技巧[*居中的是Firefox中的标准样式,该答案的JSFiddle中的“规范化CSS”选项已将其删除]

44

你有你的插入<table><div>,它有固定的尺寸,并且在<div>风格,你必须设置overflow: scroll


1
为我的div设置了500px的高度,效果很好。<div style =“ overflow:scroll; height:500px;”>
Ziggler,2013年

3
不知道为什么每个人都这么复杂。这应该是公认的答案。
amallard '18

1
到目前为止,这是最简单的解决方案。添加一个具有溢出和固定高度的div可能会有一些警告,但是此解决方案至少会为您设定正确的方向。
lsimonetti

1
一流的搭档!为您
加油

1
这应该是公认的答案。简单,直截了当,我不会破坏任何其他东西。
我尽力而为,但我哭得更厉害

40

可接受的答案提供了一个很好的起点,但是如果您调整框架的大小,更改列的宽度,甚至更改表数据,则标题将以各种方式被弄乱。我见过的每个其他示例都有类似的问题,或者对表的布局施加了一些严格的限制。

我想我终于解决了所有这些问题。花了很多CSS,但是最终产品与普通表一样可靠且易于使用。

这是一个示例,该示例具有复制OP引用的表所需的所有必需功能:jsFiddle

必须更改颜色和边框以使其与参考相同。CSS注释中提供了有关如何进行此类更改的信息。

这是代码:

/*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

哦,等等,没有水平滚动条,表格会被切断。
nanker

@nanker如果需要水平滚动并且愿意使用一点点JavaScript,则应检查此答案。这是我所知道的制作滚动表的最佳方法。发布此答案时,没有很好的方法仅靠CSS进行水平滚动,但是我已经有一段时间没有研究它了,所以我不知道现在有什么可能。
DoctorDestructo

很棒的工作。您能否评论一下如何调整多个标题行?简单地重复<tr><th></th>..</tr>构造显然是行不通的。谢谢。
David I. McIntosh

@ DavidI.McIntosh使用此技术,多行标头会很棘手。添加行很容易,但是我不确定如何获得它们之间的水平边界。除非由于某种原因不能使用JS,否则您可能想尝试我在上一条注释中链接的JavaScript解决方案。
DoctorDestructo

3

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

标题行是一个表。

秒也是<table>标签,但包裹<div>着静态高度和溢出滚动。


1

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

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

此外,如果需要,您可以使用overflow-xoverflow-y,并且显然,同一事物可以与width : x;


0

如果您发现所有提到的解决方案都不起作用(对我而言如此),请执行以下操作:

  • 创建两个表。一个用于标题,另一个用于正文
  • 给两个表不同的父容器/ 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的答案的实现方式相同。
TylerH '18 -10-26

0

只需在桌子上添加

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;”`

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.