Как я могу позволить телу прокручивать тело, но держать его неподвижно на месте? - PullRequest
144 голосов
/ 25 сентября 2008

Я пишу страницу, где мне нужна таблица HTML для поддержания заданного размера. Мне нужны заголовки в верхней части таблицы, чтобы они всегда оставались там, но мне также нужно прокручивать тело таблицы независимо от того, сколько строк добавлено в таблицу. Вспомните мини-версию Excel. Это кажется простой задачей, но почти каждое решение, которое я нашел в Интернете, имеет некоторый недостаток. Как я могу решить это?

Ответы [ 18 ]

53 голосов
/ 30 сентября 2008

Я должен был найти тот же ответ. Лучший пример, который я нашел, это http://www.cssplay.co.uk/menu/tablescroll.html - я обнаружил, что пример №2 хорошо сработал для меня. Вам нужно будет установить высоту внутренней таблицы с помощью Java Script, остальное - CSS.

34 голосов
/ 18 декабря 2011

Я нашел DataTables довольно гибким. Хотя его версия по умолчанию основана на jquery, есть также плагин AngularJs .

12 голосов
/ 11 октября 2012

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

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

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

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

8 голосов
/ 25 сентября 2008

Вы пытались использовать thead и tbody и устанавливать фиксированную высоту для tbody с помощью overflow: scroll?

Какие у вас целевые браузеры?

РЕДАКТИРОВАТЬ: Это работало хорошо (почти) в Firefox - добавление вертикальной полосы прокрутки вызвало необходимость горизонтальной полосы прокрутки - гадость IE просто устанавливает высоту каждого td на то, что я указал высоту tbody. Вот лучшее, что я мог придумать:

<html>
    <head>
    <title>Blah</title>
    <style type="text/css">
    table { width:300px; }
    tbody { height:10em;  overflow:scroll;}
    td { height:auto; }
    </style>
    </head>
    <body>
    <table>
        <thead>
            <tr>
              <th>One</th><th>Two</th>
              </td>
            </tr>
        </thead>
        <tbody>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
        </tbody>
    </table>
    </body>
</html>
7 голосов
/ 11 мая 2014

Что вам нужно, это:

1) имеет тело таблицы ограниченной высоты , поскольку прокрутка происходит только тогда, когда содержимое больше окна прокрутки. Однако размер tbody не может быть измерен, и вы должны отобразить его как block, чтобы сделать это:

tbody {
   overflow-y: auto;
   display: block;
   max-height: 10em;    // For example
}

2) Повторная синхронизация заголовков таблицы и ширины столбцов тела таблицы , поскольку создание последнего * block сделало его несвязанным элементом. Единственный способ сделать это - симулировать синхронизацию с помощью , обеспечивающей одинаковую ширину столбцов для обоих .

Однако, поскольку tbody сам по себе является block, он больше не может вести себя как table. Поскольку вам все еще нужно поведение table для правильного отображения столбцов, решение состоит в том, чтобы запросить отображение каждой из ваших строк как отдельных table s:

thead {         
   display: table;  
   width: 100%;     // Fill the containing table
}
tbody tr {
   display: table;
   width: 100%;     // Fill the containing table
}

(Обратите внимание, что, используя эту технику, вы больше не сможете охватывать строки).

Как только это будет сделано, вы можете принудительно установить одинаковую ширину столбцов в thead и tbody. Вы не могли этого:

  • индивидуально для каждого столбца (с помощью определенных классов CSS или встроенного стиля), что довольно утомительно для каждого экземпляра таблицы;
  • единообразно для всех столбцов (например, th, td { width: 20%; }, если у вас есть 5 столбцов), что более практично (не нужно устанавливать ширину для каждого экземпляра таблицы), но не может работать для любого количества столбцов
  • единообразно для любых столбцов через фиксированную разметку таблицы.

Я предпочитаю последний вариант, который требует добавления:

thead {
   table-layout: fixed;   // Same layout for all cells
}
tbody tr {
   table-layout: fixed;   // Same layout for all cells
}
th, td {
   width: auto;   // Same width for all cells, if table has fixed layout
}    

См. Демо здесь , разветвленный от ответа на на этот вопрос .

4 голосов
/ 04 мая 2012

Редактировать: Это очень старый ответ, и он здесь для процветания, чтобы показать, что он был когда-то поддержан еще в 2000-х, но упал, потому что стратегия браузеров в 2010-х состояла в том, чтобы уважать спецификации W3C, даже если некоторые были удалены функции: таблица с прокруткой с фиксированным верхним / нижним колонтитулом была неуклюже задана до HTML5.


Плохие новости

К сожалению, не существует элегантного способа обработки прокручиваемого стола с фиксированной thead / tfoot потому что спецификации HTML / CSS не очень ясны в отношении этой функции .

Пояснения

Хотя HTML 4.01 спецификация говорит, что thead / tfoot / tbody используются (представлены?) Для прокрутки тела таблицы:

Строки таблицы могут быть сгруппированы [...] с использованием элементов THEAD, TFOOT и TBODY [...]. Это разделение позволяет агентам пользователя поддерживать прокрутку тел таблицы независимо от ее головки и ножки.

Но функция рабочей прокручиваемой таблицы в FF 3.6 была удалена в FF 3.7, поскольку рассматривается как ошибка, поскольку не соответствует спецификациям HTML / CSS. См. this и , которые комментируют ошибки FF.

Совет разработчика Mozilla

Ниже приведена упрощенная версия полезных советов MDN для прокручиваемого стола
см. Эту архивную страницу или текущую французскую версию

<style type="text/css">
table {
  border-spacing: 0;              /* workaround */
}
tbody {
  height: 4em;                    /* define the height */
  overflow-x: hidden;             /* esthetics */
  overflow-y: auto;               /* allow scrolling cells */
}
td {
  border-left:   1px solid blue;  /* workaround */
  border-bottom: 1px solid blue;  /* workaround */
}
</style>

<table>
    <thead><tr><th>Header
    <tfoot><tr><th>Footer
    <tbody>
        <tr><td>Cell 1    <tr><td>Cell 2
        <tr><td>Cell 3    <tr><td>Cell 4
        <tr><td>Cell 5    <tr><td>Cell 6
        <tr><td>Cell 7    <tr><td>Cell 8
        <tr><td>Cell 9    <tr><td>Cell 10
        <tr><td>Cell 11   <tr><td>Cell 12
        <tr><td>Cell 13   <tr><td>Cell 14
    </tbody>
</table>

Однако MDN также говорит , что больше не работает на FF :-(
Я также проверил на IE8 => таблица не прокручивается либо: - ((

3 голосов
/ 04 сентября 2014

Это решение работает в Chrome 35, Firefox 30 и IE 11 (другие версии не тестировались)

Это чистый CSS: http://jsfiddle.net/ffabreti/d4sope1u/

Все настроено на отображение: блок, столу нужна высота:

    table {
        overflow: scroll;
        display: block;    /*inline-block*/
        height: 120px;
    }
    thead > tr  {
        position: absolute;
        display: block;
        padding: 0;
        margin: 0;
        top: 0;
        background-color: gray;
    }
    tbody > tr:nth-of-type(1) {
        margin-top: 16px;
    }
    tbody tr {
        display: block;
    }

    td, th {
        width: 70px;
        border-style:solid;
        border-width:1px;
        border-color:black;
    }
3 голосов
/ 06 августа 2010

Не уверен, что если кто-то все еще смотрит на это, но он, как я делал это ранее, должен использовать две таблицы для отображения одной исходной таблицы - первая - просто строка заголовка исходной таблицы и никаких строк тела таблицы (или пустого тела) строка для проверки).

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

Вторая таблица в ее div находится чуть ниже первой таблицы в HTML и выглядит как отдельная таблица с фиксированным заголовком и прокручиваемой нижней частью. Я проверял это только в Safari, Firefox и IE (последние версии каждой из них весной 2010 года), но он работал во всех из них.

Единственная проблема, с которой он сталкивался, заключалась в том, что первая таблица не могла быть проверена без тела (валидатор W3.org - строго по XHTML 1.0), и когда я добавлял таблицу без содержимого, это приводило к пустой строке. Вы можете использовать CSS, чтобы сделать это невидимым, но оно все равно будет занимать место на странице.

2 голосов
/ 25 сентября 2008

Это вызвало у меня огромные головные боли, пытаясь реализовать такую ​​сетку для нашего приложения. Я испробовал все различные техники, но у каждого из них были проблемы. Самое близкое, что я нашел, - это использование плагина jQuery, такого как Flexigrid (альтернативы можно найти на http://www.ajaxrain.com), но, похоже, он не поддерживает таблицы шириной 100%, что мне и нужно.

То, что я в итоге делал, катало меня; Firefox поддерживает прокрутку tbody элементов, поэтому я просматривал браузер и использовал соответствующий CSS (установил высоту, переполнение и т. Д., Спрашивал, хотите ли вы больше подробностей), чтобы сделать эту прокрутку, а затем для других браузеров я использовал две отдельные таблицы, установленные для использования table-layout: fixed, который использует алгоритм определения размера, гарантирующий, что он не будет превышать указанный размер (обычные таблицы будут расширяться, когда содержимое слишком широкое, чтобы уместиться). Придав обеим таблицам одинаковую ширину, я смог выстроить их столбцы. Я обернул второй в наборе элементов для прокрутки, и немного поиграв в покер с полями и т. Д. Мне удалось получить тот внешний вид, который я хотел.

Извините, если этот ответ звучит немного расплывчато; Я пишу быстро, потому что у меня мало времени. Оставьте комментарий, если хотите, чтобы я продолжал расширяться!

2 голосов
/ 24 января 2011

Вот код, который действительно работает для IE и FF (по крайней мере):

<html>
<head>
    <title>Test</title>
    <style type="text/css">
        table{
            width: 400px;
        }
        tbody {
            height: 100px;
            overflow: scroll;
        }
        div {
            height: 100px;
            width: 400px;
            position: relative;
        }
        tr.alt td {
            background-color: #EEEEEE;
        }
    </style>
    <!--[if IE]>
        <style type="text/css">
            div {
                overflow-y: scroll;
                overflow-x: hidden;
            }
            thead tr {
                position: absolute;
                top: expression(this.offsetParent.scrollTop);
            }
            tbody {
                height: auto;
            }
        </style>
    <![endif]--> 
</head>
<body>
    <div >
        <table border="0" cellspacing="0" cellpadding="0">
            <thead>
                <tr>
                    <th style="background: lightgreen;">user</th>
                    <th style="background: lightgreen;">email</th>
                    <th style="background: lightgreen;">id</th>
                    <th style="background: lightgreen;">Y/N</th>
                </tr>
            </thead>
            <tbody align="center">
                <!--[if IE]>
                    <tr>
                        <td colspan="4">on IE it's overridden by the header</td>
                    </tr>
                <![endif]--> 
                <tr>
                    <td>user 1</td>
                    <td>user@user.com</td>
                    <td>1</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 2</td>
                    <td>user@user.com</td>
                    <td>2</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 3</td>
                    <td>user@user.com</td>
                    <td>3</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 4</td>
                    <td>user@user.com</td>
                    <td>4</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 5</td>
                    <td>user@user.com</td>
                    <td>5</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 6</td>
                    <td>user@user.com</td>
                    <td>6</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 7</td>
                    <td>user@user.com</td>
                    <td>7</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 8</td>
                    <td>user@user.com</td>
                    <td>8</td>
                    <td>N</td>
                </tr>
            </tbody>
        </table>
    </div>
</body></html>

Я изменил исходный код, чтобы сделать его более понятным, а также чтобы он работал нормально в IE и в FF ..

Оригинальный код ЗДЕСЬ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...