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

时间:2011-11-22 19:38:45

标签: html css scroll html-table overflow

我正在编写一个页面,我需要一个html表来维护一个设置的大小。我需要表格顶部的标题始终保持在那里,但无论表格中添加了多少行,我还需要滚动表格的主体。

我希望它看起来像这个网址中的方法2:http://www.cssplay.co.uk/menu/tablescroll.html

我尝试过这样做但没有滚动条出现:

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

CSS:

tbody { 
    height:80em;  
    overflow:scroll;
                }

10 个答案:

答案 0 :(得分:143)

这样的东西?

http://jsfiddle.net/TweNm/

我们的想法是将<table>包装在具有<div> CSS属性的非静态定位overflow:auto中。然后绝对地将元素放在<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>

答案 1 :(得分:35)

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

我想我终于解决了所有这些问题。它需要一个很多的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]-->

答案 2 :(得分:32)

您必须将表插入到具有固定大小的div中,并且在div样式中您必须设置overflow:scroll。

答案 3 :(得分:3)

不知道为什么没有人提到只对元素使用内置的粘性标题样式。对我很有用。

.tableContainerDiv {
   overflow: auto;
   max-height: 80em;
}
th {
   position: sticky;
   top: 0;
   background: white;
}

如果您需要做出响应(或类似),请在 @media 中设置最小宽度。

Table headers position:stickyPosition Sticky and Table Headers

答案 4 :(得分:2)

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

一个表是标题行。

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

答案 5 :(得分:0)

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

如果您需要,请将#reference: http://pandas.pydata.org/pandas-docs/stable/10min.html #reference: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html. import numpy as np import pandas as pd def df_dupes(df_in): ''' Returns [object,count] pairs for each unique item in the dataframe. ''' # import pandas if isinstance(df_in, list) or isinstance(df_in, tuple): import pandas as pd df_in = pd.DataFrame(df_in) return df_in.groupby(df_in.columns.tolist(),as_index=False).size() def df_filter_example(df): ''' In [96]: df Out[96]: A B C D 0 1 4 9 1 1 4 5 0 2 2 5 5 1 0 3 1 3 9 6 ''' import pandas as pd df=pd.DataFrame([[1,4,9,1],[4,5,0,2],[5,5,1,0],[1,3,9,6]],columns=['A','B','C','D']) return df[(df.A == 1) & (df.D == 6)] def df_compare(df1, df2, compare_col_list, join_type): ''' df_compare compares 2 dataframes. Returns left, right, inner or outer join df1 is the first/left dataframe df2 is the second/right dataframe compare_col_list is a lsit of column names that must match between df1 and df2 join_type = 'inner', 'left', 'right' or 'outer' ''' import pandas as pd return pd.merge(df1, df2, how=join_type, on=compare_col_list) def df_compare_examples(): import numpy as np import pandas as pd df1=pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns = ['c1', 'c2', 'c3']) ''' c1 c2 c3 0 1 2 3 1 4 5 6 2 7 8 9 ''' df2=pd.DataFrame([[4,5,6],[7,8,9],[10,11,12]], columns = ['c1', 'c2', 'c3']) ''' c1 c2 c3 0 4 5 6 1 7 8 9 2 10 11 12 ''' # One can see that df1 contains 1 row ([1,2,3]) not in df3 and # df2 contains 1 rown([10,11,12]) not in df1. # Assume c1 is not relevant to the comparison. So, we merge on cols 2 and 3. df_merge = pd.merge(df1,df2,how='outer',on=['c2','c3']) print(df_merge) ''' c1_x c2 c3 c1_y 0 1 2 3 NaN 1 4 5 6 4 2 7 8 9 7 3 NaN 11 12 10 ''' ''' One can see that columns c2 and c3 are returned. We also received columns c1_x and c1_y, where c1_X is the value of column c1 in the first dataframe and c1_y is the value of c1 in the second dataframe. As such, any row that contains c1_y = NaN is a row from df1 not in df2 & any row that contains c1_x = NaN is a row from df2 not in df1. ''' df1_unique = pd.merge(df1,df2,how='left',on=['c2','c3']) df1_unique = df1_unique[df1_unique['c1_y'].isnull()] print(df1_unique) df2_unique = pd.merge(df1,df2,how='right',on=['c2','c3']) print(df2_unique) df_common = pd.merge(df1,df2,how='inner',on=['c2','c3']) print(df_common) def delete_column_example(): print 'create df' import pandas as pd df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns=['a','b','c']) print 'drop (delete/remove) column' col_name = 'b' df.drop(col_name, axis=1, inplace=True) # or df = df.drop('col_name, 1) def delete_rows_example(): print '\n\ncreate df' import pandas as pd df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns=['col_1','col_2','col_3']) print(df) print '\n\nappend rows' df= df.append(pd.DataFrame([[11,22,33]], columns=['col_1','col_2','col_3'])) print(df) print '\n\ndelete rows where (based on) column value' df = df[df.col_1 == 4] print(df) 替换为height: x;,将max-height: x;替换为overflow:scroll

此外,如果您愿意,可以使用overflow:autooverflow-x,显然同样的事情可以与overflow-y水平对齐

答案 6 :(得分: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 
    }

答案 7 :(得分: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;”`

答案 8 :(得分:0)

非常容易,只需将表包装在具有overflow-y:scroll;overflow-x:scroll属性的div中,并使div的宽度和长度小于表的长度。 它会工作的!!

答案 9 :(得分:0)

CSS: div{ overflow-y:scroll; overflow-x:scroll; width:20px; height:30px; } table{ width:50px; height:50px; }

您可以使表格和表格周围的DIV为您想要的任何大小,只需确保DIV小于表格即可。 您必须将表格包含在DIV中。