使TBODY在Webkit浏览器中可滚动


70

我知道这个问题,但所有答案都无法在Safari,Chrome等系统中使用。

可以接受的策略(如此处所示)是设置躯干高度和溢出属性,如下所示:

<table>
    <thead>
        <tr><th>This is the header and doesn't scroll</th></tr>
    </thead>
    <tbody style="height:100px; overflow:auto;">
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
    </tbody>
</table>

不幸的是,这不适用于任何Webkit浏览器。关于它的错误报告似乎没有被高度重视(报告于6月5日)。

所以我的问题是:是否有其他切实可行的替代策略?我尝试了两表方法,但是无法保证标题将与内容对齐。我是否只需要等待Webkit对其进行修复?

Answers:


33

这是一个工作示例:

http://www.imaputz.com/cssStuff/bigFourVersion.html

您必须将display:block添加到thead> tr和tbody


@CristianBoariu不是吗?:(
Andreas Wong

1
@Michael Koper我真的很喜欢这个。不幸的是,它在IE9上不起作用:(

3
这在IE 9上完全失败,像imho这样的解决方案是无法接受的。没有回退,在IE上它根本不显示任何表行!
约翰

7
仅当每个像元的设定长度相同时,此方法才有效。可以使用弹性表进行这项工作吗?
路灯

24
这不是解决方案。表格的整个要点是具有与表格内显示的数据点动态对齐的列。在标题上设置固定宽度最终只会导致表格未对齐。努力在浏览器中正确显示表格数据的斗争……叹息
RavenHursT 2014年

17

仅当您有1列时,才使用display:block样式。如果您有多个数据列-具有多个字段-那么display:block似乎使所有数据列都可滚动但在第一列下方(在Firefox中也是如此-这是我所知道的唯一浏览器无法很好地滚动)。顺便提一下,在Firefox上,您可以使用overflow-x:隐藏样式抑制水平滚动。

我意识到,仅当您没有为th&td元素指定宽度时,才会出现我提到的问题-如果您可以固定列宽,则它可以工作。我的问题是我无法固定列宽。


7
“对我来说,问题是我无法固定列宽。” 正是我的问题。= /
安德鲁·恩斯利

2
对我来说,也无法固定列宽
2012年



5

我看到了肖恩·哈迪的出色解决方案,并自由地进行了一些编辑

  • 使用类代替ID,因此一个jQuery脚本可在一页上重用于多个表
  • 添加了对语义HTML表格元素的支持,例如标题,thead,tfoot和tbody
  • 将滚动条设置为可选,以便它不会出现在比可滚动高度“短”的表中
  • 调整滚动div的宽度,使滚动条向上到表格的右边缘
  • 使概念可由
    • 在注入的静态表头上使用aria-hidden =“ true”
    • 并保留原始thead到位,只是用jQuery和set隐藏 aria-hidden="false"
  • 显示了具有不同大小的多个表的示例

肖恩做了繁重的工作。还要感谢马特·伯兰德(Matt Burland)指出需要支撑脚。

请访问http://jsfiddle.net/jhfrench/eNP2N/


3

一个很久以前就面临着同样的问题,我终于提出了两个表的方法。结果是:http : //jsfiddle.net/bGr4V/3/,它适用于所有浏览器(IE6 + incl)。

这个jsFiddle中,您可以使用干净的版本。

我的解决办法是增加一个修复细胞 <th class="fix"> </th>thead,以填补在所述滚动条的空间tbody,然后给一列的可变宽度(<td class="grow">),所以头修复细胞不会对调整大小的不匹配。

HTML:

<div class="fixed_table">
  <div class="head">
    <table>
      <thead>
        <tr>
          <th>Column header</th>
          <th class="grow">Column header</th>
          <th class="fix"> </th>
        </tr>
      </thead>
    </table>
  <div class="body">
    <table class="full_table">
      <caption class="caption">Caption</caption>
      <tbody>
        <tr>
          <td>Data</td>
          <td class="grow">Data</td>
        </tr>
        <tr>
          <td>...</td>
          <td>...</td>
        </tr>
        <tr>
          <td>...</td>
          <td>...</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

CSS:针对ie6-7具有has*_hack,在每种情况下都有-webkit针对头固定单元匹配滚动宽度的特定功能。

.fixed_table table {
  table-layout: fixed;
  width: auto;
  border-width: 0;
  padding: 0;
  border-collapse: collapse;
}

.fixed_table .body {
  overflow: scroll;
  overflow-x: hidden;
  max-height: 10.75em;
  min-height: 2.5em;
  padding-bottom: 0.8em;
  *padding-right: 17px; /*ie7 & ie6*/
  _padding-right: 0; /*ie6*/
  _height: 10em ;
}

.fixed_table th, .fixed_table td {
  width: 4.7em;
}

.fixed_table .grow {
  width: auto;
}

.fixed_table .fix {
  width: 16px;
  *width: 17px; /*ie7 & ie6*/
  _width: 16px; /*ie6*/
}

/* webkit specific */
@media screen and (-webkit-min-device-pixel-ratio:0) {
  .fixed_table .fix{ width: 17px }
}

2

以为我会把解决方案混在一起-http: //tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/

它采用与@Michael Koper的解决方案相同的基本路线,但包含一种解决方法,因此该表在IE6中看上去可以正确地返回IE6。

我通过给<table>atable-layout: fixed并显式地将宽度分配给每一列中的单元格来解决宽度问题。这并不理想,但是它确实生成了一个语义表,该语义表将与跨浏览器对齐,而不管是否需要滚动条。

演示:http//codepen.io/tjvantoll/pen/JEKIu


1

我针对上述问题开发了javascript解决方案,该解决方案
仅在Firefox 7+中有效,因为我仅在FF中进行了测试,

我来到了此线程并找到了Michael Koper指出的解决方案

在此解决方案中,完成了三件事:
1)固定列宽
2)thead> tr显示设置为块
3)tbody显示设置为块

正如其他人提到的,固定宽度存在问题,我也处于同一位置;
即使我不能固定宽度

所以我想我会动态修复宽度(在浏览器中渲染表格后),这确实可以解决问题:)

以下是javascript中仅在FF中有效的解决方案
(我仅在FF中进行过测试,我无法访问其他浏览器)

       function test1(){                
            var tbodys = document.getElementsByTagName("TBODY");
            for(var i=0;i<tbodys.length;i++){
                do_tbodyscroll(tbodys[i]);
            }
        }


      function do_tbodyscroll(_tbody){
            // get the table node 
            var table = _tbody.parentNode;

            // first row of tbody 
            var _fr = _tbody.getElementsByTagName("TR")[0];

            // first row cells .. 
            var _frcells = _fr.cells;

            // Width array , width of each element is stored in this array 
            var widtharray = new Array(_frcells.length);

            for(var i=0;i<_frcells.length;i++){                    
                widtharray[i] = _frcells[i].scrollWidth;
            }                

            // Apply width to first row                  
            for(var i=0;i<_frcells.length;i++){
                _frcells[i].width = widtharray[i];                   
            }                 

            // Get the Last row in Thead ... 
            // COLGROUPS USING COLSPAN NOT YET SUPPORTED

            var thead = table.getElementsByTagName("THEAD")[0];
            var _rows = thead.getElementsByTagName("TR");
            var tableheader = _rows[_rows.length - 1];
            var headercells = tableheader.cells;

            // Apply width to header ..                                
            for(var i=0;i<headercells.length;i++){
                headercells[i].width = widtharray[i];
            }

            // ADD 16 Pixel of scroll bar to last column ..
            headercells[headercells.length -1 ].width = widtharray[headercells.length -1] + 16;

            tableheader.style.display = "block";
            _tbody.style.display = "block";  
        }

该解决方案从浏览器中找出列的宽度,
并在设置宽度后再次将相同的宽度设置为列(tbody的标题和第一行)
;thead> tr和tbody显示设置为阻止

希望此解决方案对大家有用..
如果您可以将其扩展到其他浏览器,请回复此帖子


1
重要的一件事是,
琴身

1

这确实很hacky,但也许可以帮助某个地方的人...

http://jsfiddle.net/yUHCq/1/

它使用列而不是行,因此处理基本上是向后进行的。

添加了过渡DOCTYPE以实现IE兼容性。


5
人们会因为这种事情而被送入CSS地狱吗?
马修

1
那不是<tbody>元素,更不用说表格元素了,因此不要回答这个问题(标题留给想象的空间很小)。
Rob W

1

对于这个问题,这可能有些矫kill过正,但是YUI仍然可能提供最佳的免费跨浏览器数据表。它也可以用于只读数据。

YUI 2数据表

YUI 3数据表

单击那里的示例以查看可滚动的示例。因为我是stackoverflow的新手,所以我只能发布这两个链接。


0

添加display:block;这还将删除FireFox中不必要的水平滚动。毫无疑问,您还知道在MSIE 8中这两个示例都不起作用。

<table>
    <thead>
        <tr><th>This is the header and doesn't scroll</th></tr>
    </thead>
    <tbody style="height:100px; overflow:auto;display:block;">
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
        <tr><td>content that scrolls</td></tr>
    </tbody>
</table>

6
多列不是问题中给出的示例的一部分。
2011年

2
@mmcglynn:尽管这可能是正确的,但首先要这样做的唯一原因是使用多列表,因此这是一个合理的假设。不要把所有问题都当成是面子。
Matti Virkkunen 2014年

当然,将来我会添加示例中未包含的标记,并将其与您对问题的解释进行交叉引用。
mmcglynn 2014年


0

如果有人需要它在IE quirks模式下工作,这就是我更改和简化IG Pascual的代码的工作方式:

.fixed_table{
       overflow: scroll;
       overflow-x: hidden;
       max-height: 300px;
       height: 300px;
       min-height: 50px;
       padding-right:0;
}
#datatable td 
{
       padding:3px;
       text-align: center;
       width: 9%;
       vertical-align: middle;
       background-color: #343435; 
       color: #E0E0E3;
       overflow:hidden;
} 
<div class="head">
    <table>
        <thead>
            <tr>
                <th>Time (GMT)</th>
                <th>Price</th>
            </tr>
        </thead>
    </table>
</div>
<div class="fixed_table">
    <table id="datatable" cellspacing="1" cellpadding="1">
        <tbody></tbody>
    </table>
</div>

0

让表格按其方式绘制并计算每列的宽度并将其设置到每个标题中。标题由分隔组成,然后我们可以使表格自由滚动。

<!DOCTYPE html>
<html>
<head>
<style>
.t_heading{
  margin-top: 20px;
  font-family: Verdana, Geneva, sans-serif;
  background-color: #4CAF50;
}

.heading{
  background-color: #4CAF50;
  color: white;
  float:left;
  padding: 8px 0PX 8PX 0PX;
  border-bottom: 1px solid #ddd;
  height: 20px;
  text-align: left;
}

.t_data{
  overflow-y: scroll;
  overflow-x: hidden;
  height:0px;
  width: 100%;

}

.t_content{
    border-collapse: collapse;
    font-family: Verdana, Geneva, sans-serif;
    width: 100%;
}

.column1,.column2,.column3,.column4{
    padding: 8px 0PX 8PX 0PX;
    text-align: left;
    border-bottom: 1px solid #ddd;
}
.t_row:hover{
  background-color:#f5f5f5;
}
</style>
<script>
function setBody(){
    var body = document.body,
    html = document.documentElement;

    var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
    height = height-300;
    /*
     ** By changing the subtraction value, You can fit the table in to the screen correctly.
     ** Make sure not to come the hscroll.
     ** Or you can set fixed height with css for the div as your wish.
     */
    document.getElementById("t_data").style.height = height+"px";

    setColumnWidth("column1");
    setColumnWidth("column2");
    setColumnWidth("column3");
    setColumnWidth("column4");
}

function setColumnWidth(o){
        var object = o;
        var x = document.getElementsByClassName(object);
        var y = x[0].clientWidth;
        document.getElementById(object).style.width = y+"px";
 }
</script>
</head>

<body onload="setBody()">
<div class="t_heading">
<div class="heading"  id="column1">Heading 1</div>
<div class="heading"  id="column2">Heading 2</div>
<div class="heading"  id="column3">Heading 3</div>
<div class="heading"  id="column4">Heading 4</div>
</div>
<div class="t_data" id="t_data">
<table class="t_content">
    <tr class='t_row'>
        <td class='column1'>Column1 Row 0</td>
        <td class='column2'>Column2 Row 0</td>
        <td class='column3'>Column3 Row 0</td>
        <td class='column4'>Column4 Row 0</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 1</td>
        <td class='column2'>Column2 Row 1</td>
        <td class='column3'>Column3 Row 1</td>
        <td class='column4'>Column4 Row 1</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 2</td>
        <td class='column2'>Column2 Row 2</td>
        <td class='column3'>Column3 Row 2</td>
        <td class='column4'>Column4 Row 2</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 3</td>
        <td class='column2'>Column2 Row 3</td>
        <td class='column3'>Column3 Row 3</td>
        <td class='column4'>Column4 Row 3</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 4</td>
        <td class='column2'>Column2 Row 4</td>
        <td class='column3'>Column3 Row 4</td>
        <td class='column4'>Column4 Row 4</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 5</td>
        <td class='column2'>Column2 Row 5</td>
        <td class='column3'>Column3 Row 5</td>
        <td class='column4'>Column4 Row 5</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 6</td>
        <td class='column2'>Column2 Row 6</td>
        <td class='column3'>Column3 Row 6</td>
        <td class='column4'>Column4 Row 6</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 7</td>
        <td class='column2'>Column2 Row 7</td>
        <td class='column3'>Column3 Row 7</td>
        <td class='column4'>Column4 Row 7</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 8</td>
        <td class='column2'>Column2 Row 8</td>
        <td class='column3'>Column3 Row 8</td>
        <td class='column4'>Column4 Row 8</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 9</td>
        <td class='column2'>Column2 Row 9</td>
        <td class='column3'>Column3 Row 9</td>
        <td class='column4'>Column4 Row 9</td>
    </tr><tr class='t_row'>
        <td class='column1'>Column1 Row 10</td>
        <td class='column2'>Column2 Row 10</td>
        <td class='column3'>Column3 Row 10</td>
        <td class='column4'>Column4 Row 10</td>
    </tr>
<!--
<?php
$data = array();
for($a = 0; $a<50; $a++)
{
    $data[$a] = array();
    $data[$a][0] = "Column1 Row ".$a;
    $data[$a][1] = "Column2 Row ".$a;
    $data[$a][2] = "Column3 Row ".$a;
    $data[$a][3] = "Column4 Row ".$a;
}
/*
 ** supose you have data in an array.. which red from database. The table will draw using array data. Or you can draw the table manualy.
 ** tip: If using manual table, No need of
 ** 'var x = document.getElementsByClassName(object); var y = x[0].clientWidth;'.
 ** You can just set ID of first row's cells in to some name and use it to read width.
 */
for($i=0;$i<sizeof($data);$i++){
    echo "<tr class='t_row'><td class='column1'>".$data[$i][0]."</td><td class='column2'>".$data[$i][1]."</td><td class='column3'>".$data[$i][2]."</td><td class='column4'>".$data[$i][3]."</td></tr>";
}
?>
-->
</table>
</div>
</body>
</html>
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.