Сделайте TBODY прокручиваемым в браузерах Webkit

Мне известен этот вопрос, но ни один из ответов не работает в Safari, Chrome и т. Д.

Принятая стратегия ( как показано здесь) состоит в том, чтобы установить tbody height и свойства переполнения следующим образом:

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

К сожалению, это не работает ни в одном веб-браузере. Об этом есть сообщение об ошибке, которое не является приоритетным (от 05 июня).

Итак, мой вопрос: есть ли альтернативные стратегии, которые действительно работают? Я пробовал подход с двумя таблицами, но невозможно гарантировать, что заголовок будет соответствовать содержанию. Должен ли я ждать, пока Webkit это исправит?

14 ответов

Решение

Вот рабочий пример:

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

Вы должны добавить блок display: thead > tr и tbody

Использование отображения: стиль блока работает, только если у вас есть 1 столбец. Если у вас есть несколько столбцов данных - с несколькими полями - тогда отобразится display:block, чтобы прокрутить все столбцы данных, но под 1-м столбцом (делает то же самое в Firefox - единственном браузере, который я знаю, который хорошо прокручивает). Кстати, в Firefox вы можете использовать стиль overflow-x: hidden для подавления горизонтальной прокрутки.

Я понял, что проблема, о которой я упоминаю, возникает, только если вы не указываете ширину для элементов th & td - если вы можете исправить ширину столбцов, тогда это работает. Проблема для меня в том, что я не могу исправить ширину столбца.

Попробуйте первый метод на этой странице, чистый CSS с одной таблицей (2 деления вокруг таблицы, и thead позиционируется абсолютно): http://www.cssplay.co.uk/menu/tablescroll.html Кажется, что работать над FF4/IE9/IE8 в дополнение к IE7/FF3.6.

У меня была та же проблема, и я написал скрипт jQuery, чтобы сделать это для меня... использует два элемента таблицы и соответственно форматирует CSS. Надеюсь, что это помогает другим, у кого такая же проблема...

http://jsfiddle.net/pe295/1/

Я увидел отличное решение Шона Хэдди и позволил себе внести некоторые изменения:

  • Используйте классы вместо ID, чтобы один сценарий jQuery можно было повторно использовать для нескольких таблиц на одной странице
  • Добавлена ​​поддержка семантических элементов таблицы HTML, таких как caption, thead, tfoot и tbody
  • Добавлена ​​опция полосы прокрутки, чтобы она не отображалась для таблиц, которые "короче" высоты прокрутки
  • Скорректирована ширина прокрутки div, чтобы полоса прокрутки доходила до правого края таблицы
  • Сделал концепцию доступной
    • использование aria-hidden="true" для вставленного статического заголовка таблицы
    • и оставив оригинальную thead на месте, просто скрытый с помощью jQuery и установлен aria-hidden="false"
  • Показаны примеры нескольких таблиц с разными размерами

Шон сделал тяжелую работу, хотя. Спасибо Мэтту Берленду за то, что он указал на необходимость поддержки tfoot.

Пожалуйста, убедитесь сами на http://jsfiddle.net/jhfrench/eNP2N/

Я давно столкнулся с той же проблемой, и я, наконец, изложил подход с двумя таблицами. Это результат: http://jsfiddle.net/bGr4V/3/, он работает для всех браузеров (IE6+ вкл).

В этом 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, и -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 }
}

Думал, я бы бросил свое решение в смесь - http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/.

Он использует тот же базовый маршрут, что и решение @Michael Koper, но включает обходной путь, поэтому таблица будет выглядеть корректно в IE обратно в IE6.

Я решаю проблему ширины, давая <table> table-layout: fixed и явное присвоение ширины ячейкам в каждом столбце. Не идеально, но он создает семантическую таблицу, которая выровняет кросс-браузер независимо от того, нужна ли полоса прокрутки.

Демо: http://codepen.io/tjvantoll/pen/JEKIu

Это может быть излишним в этом вопросе, но YUI по-прежнему предоставляет, возможно, лучший бесплатный кросс-браузерный набор данных. Он также может использоваться для данных только для чтения.

YUI 2 DataTable

YUI 3 DataTable

Нажмите на примеры там, чтобы увидеть прокручиваемые образцы. Поскольку я новичок в stackru, я могу публиковать только эти две ссылки.

Я разработал решение JavaScript для вышеуказанной проблемы
который работает только в Firefox 7+, как я тестировал только в FF

Я пришел к этой теме и нашел решение, на которое указал Майкл Копер

В этом решении три важные вещи сделаны
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";  
        }

Это решение выясняет, какова ширина столбца из браузера
и снова установите ту же ширину для столбцов (заголовок и первый ряд тела)
после того, как ширина установлена; thead > tr и tbody дисплей блокируется

Надеюсь, что это решение полезно для всех вас..
если вы можете распространить его на другие браузеры, пожалуйста, ответьте на этот пост

Это действительно довольно странно, но, может быть, это кому-то поможет...

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

Он использует столбцы вместо строк, поэтому его обработка в основном будет выполняться в обратном направлении.

Переходный DOCTYPE добавлен для совместимости с IE.

Здесь есть пример, который работает в IE5+, Firefox и Chrome. Тем не менее, он использует столбцы фиксированной ширины. http://www.cssplay.co.uk/menu/tablescroll.html

Позвольте таблице рисовать как есть, рассчитайте ширину каждого столбца и установите его для каждого заголовка. Заголовки делятся на разделы, и тогда мы можем позволить таблице прокручиваться бесплатно.

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

Если кому-то это нужно для работы в режиме 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>

Добавлять 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>
Другие вопросы по тегам