HTML-таблица шириной 100% с вертикальной прокруткой внутри тела

423

Как я могу установить <table>ширину 100% и поместить только в <tbody>вертикальную прокрутку для некоторой высоты?

вертикальная прокрутка внутри тела

table {
    width: 100%;
    display:block;
}
thead {
    display: inline-block;
    width: 100%;
    height: 20px;
}
tbody {
    height: 200px;
    display: inline-block;
    width: 100%;
    overflow: auto;
}
  
<table>
  <thead>
    <tr>
    	<th>Head 1</th>
    	<th>Head 2</th>
    	<th>Head 3</th>
    	<th>Head 4</th>
    	<th>Head 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
    	<td>Content 1</td>
    	<td>Content 2</td>
    	<td>Content 3</td>
    	<td>Content 4</td>
    	<td>Content 5</td>
    </tr>
  </tbody>
</table>

Я хочу избежать добавления какого-либо дополнительного div, все, что мне нужно, это простая таблица, подобная этой, и когда я пытаюсь изменить отображение table-layout, positionи многое другое в таблице CSS, не работающей хорошо со 100% шириной только с фиксированной шириной в px.

Марко С
источник
Я не совсем уверен, чего ты хочешь достичь. посмотрите на это: jsfiddle.net/CrSpu и расскажите, как вы хотите, чтобы он вел себя
x4rf41
2
я знаю, но посмотрите .. th и td не показаны во всю ширину .. postimg.org/image/mgd630y61
Марко С
Связанный: stackoverflow.com/questions/1019938/…
Кристоф Руссси
Связанный: stackoverflow.com/q/4534200/435605 и stackoverflow.com/q/33075195/435605
АликЭльзин-Килака

Ответы:

675

Чтобы сделать <tbody>элемент прокручиваемым, нам нужно изменить способ его отображения на странице, т.е. использовать его display: block;для отображения в качестве элемента уровня блока.

Так как мы изменяем displayсвойство tbody, мы должны изменить это свойство и для theadэлемента, чтобы не нарушать макет таблицы.

Итак, мы имеем:

thead, tbody { display: block; }

tbody {
    height: 100px;       /* Just for the demo          */
    overflow-y: auto;    /* Trigger vertical scroll    */
    overflow-x: hidden;  /* Hide the horizontal scroll */
}

Веб - браузеры отображают theadи tbodyэлементы в виде строки-группы ( table-header-groupи table-row-group) по умолчанию.

Как только мы изменим это, внутренние trэлементы не заполняют все пространство своего контейнера.

Чтобы это исправить, мы должны вычислить ширину tbodyстолбцов и применить соответствующее значение к theadстолбцам с помощью JavaScript.

Авто ширина столбцов

Вот версия jQuery вышеупомянутой логики:

// Change the selector if needed
var $table = $('table'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
    return $(this).width();
}).get();

// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
    $(v).width(colWidth[i]);
});    

И вот вывод (на Windows 7 Chrome 32) :

вертикальная прокрутка внутри тела

РАБОЧАЯ ДЕМО .

Таблица полной ширины, столбцы относительной ширины

Поскольку оригинальный плакат требовался, мы могли бы расширить tableдо 100% widthего контейнера, а затем использовать относительный ( процент ) widthдля каждого столбца таблицы.

table {
    width: 100%; /* Optional */
}

tbody td, thead th {
    width: 20%;  /* Optional */
}

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

Следовательно, мы должны установить ширину столбцов после изменения размера окна:

// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
    /* Same as before */ 
}).resize(); // Trigger the resize handler once the script runs

Выход будет:

Жидкостный стол с вертикальной прокруткой внутри корпуса

РАБОЧАЯ ДЕМО .


Поддержка браузера и альтернативы

Я протестировал два вышеуказанных метода в Windows 7 через новые версии основных веб-браузеров (включая IE10 +), и это сработало.

Тем не менее, он не работает должным образом на IE9 и ниже.

Это связано с тем, что в макете таблицы все элементы должны иметь одинаковые структурные свойства.

Используя элементы display: block;for <thead>и <tbody>, мы нарушили структуру таблицы.

Редизайн макета с помощью JavaScript

Один из подходов заключается в перепроектировании (всей) компоновки таблицы. Использование JavaScript для создания нового макета на лету, обработки и / или динамической регулировки ширины / высоты ячеек.

Например, взгляните на следующие примеры:

Скворечники

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

Проверьте таблицы вертикальной прокрутки в CSS Play .

Это работает в большинстве веб-браузеров. Мы также можем динамически выполнять вышеуказанную логику с помощью JavaScript.

Таблица с фиксированным заголовком на свитке

С целью добавления вертикальной полосы прокрутки к <tbody>отображающей таблицы заголовка в верхней части каждой строки, мы могли бы расположить на theadэлемент , чтобы остаться fixedв верхней части экрана вместо.

Вот рабочая демонстрация этого подхода в исполнении Жюльена .
Имеет многообещающую поддержку веб-браузера.

А вот чистый CSS реализация на Willem Van Bockstal .


Чистое решение CSS

Вот старый ответ. Конечно, я добавил новый метод и уточнил объявления CSS.

Стол с фиксированной шириной

В этом случае значение tableдолжно быть фиксированным width (включая сумму ширины столбцов и ширины вертикальной полосы прокрутки) .

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

Следовательно, CSS будет:

table {
    width: 716px; /* 140px * 5 column + 16px scrollbar width */
    border-spacing: 0;
}

tbody, thead tr { display: block; }

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 140px;
}

thead th:last-child {
    width: 156px; /* 140px + 16px scrollbar width */
}

Вот вывод:

Стол с фиксированной шириной

РАБОЧАЯ ДЕМО .

Стол со 100% шириной

В этом подходе tableширина имеет 100%для каждого thи tdзначение widthсвойства должно быть меньше, чем 100% / number of cols.

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

Для этого нам нужно использовать calc()функцию CSS3 следующим образом:

table {
    width: 100%;
    border-spacing: 0;
}

thead, tbody, tr, th, td { display: block; }

thead tr {
    /* fallback */
    width: 97%;
    /* minus scroll bar width */
    width: -webkit-calc(100% - 16px);
    width:    -moz-calc(100% - 16px);
    width:         calc(100% - 16px);
}

tr:after {  /* clearing float */
    content: ' ';
    display: block;
    visibility: hidden;
    clear: both;
}

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 19%;  /* 19% is less than (100% / 5 cols) = 20% */
    float: left;
}

Вот онлайн демо .

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


Ниже приведены два простых примера чистого решения CSS, которые я создал, когда ответил на этот вопрос.

Вот демоверсия jsFiddle v2 .

Старая версия: jsFiddle Demo v1

Хашем Колами
источник
17
При этом display: blockвы теряете свойства таблицы как ширину столбца, разделяемую между thead и tbody. Я знаю, что вы исправили это путем установки, width: 19.2%но в случае, если мы не знаем ширину каждого столбца заранее, это не будет работать.
самб
10
Кажется, этот код предполагает, что клетки тела всегда будут шире, чем клетки заголовка.
Адам Донахью
2
Не работает, когда height: 100%(когда вы хотите, чтобы таблица расширилась до нижней части страницы).
Алик Эльзин-килака
2
Это также фантастически работает с ng-repeatтаблицами AngularJS . Не уверен, почему есть все эти библиотеки с фиксированными заголовками таблиц, а что нет, когда есть это решение.
chakeda
2
Вы можете немного улучшить это box-sizingсвойство, чтобы границы двух разных толщин не нарушали выравнивание столбцов.
Рикка
89

В следующем решении таблица занимает 100% родительского контейнера, абсолютные размеры не требуются. Это чистый CSS, используется гибкий макет.

Вот как это выглядит: введите описание изображения здесь

Возможные недостатки:

  • вертикальная полоса прокрутки всегда видна, независимо от того, требуется ли она;
  • фиксированный макет таблицы - размер столбцов не изменяется в соответствии с шириной содержимого (вы все равно можете явно указать любую ширину столбца);
  • есть один абсолютный размер - ширина полосы прокрутки, которая составляет около 0,9 мкм для браузеров, которые я смог проверить.

HTML (сокращенно):

<div class="table-container">
    <table>
        <thead>
            <tr>
                <th>head1</th>
                <th>head2</th>
                <th>head3</th>
                <th>head4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            ...
        </tbody>
    </table>
</div>

CSS, с некоторыми украшениями для ясности:

.table-container {
    height: 10em;
}
table {
    display: flex;
    flex-flow: column;
    height: 100%;
    width: 100%;
}
table thead {
    /* head takes the height it requires, 
    and it's not scaled when table is resized */
    flex: 0 0 auto;
    width: calc(100% - 0.9em);
}
table tbody {
    /* body takes all the remaining available space */
    flex: 1 1 auto;
    display: block;
    overflow-y: scroll;
}
table tbody tr {
    width: 100%;
}
table thead, table tbody tr {
    display: table;
    table-layout: fixed;
}

полный код на jsfiddle

Тот же код в LESS, так что вы можете смешать его в:

.table-scrollable() {
  @scrollbar-width: 0.9em;
  display: flex;
  flex-flow: column;

  thead,
  tbody tr {
    display: table;
    table-layout: fixed;
  }

  thead {
    flex: 0 0 auto;
    width: ~"calc(100% - @{scrollbar-width})";
  }

  tbody {
    display: block;
    flex: 1 1 auto;
    overflow-y: scroll;

    tr {
      width: 100%;
    }
  }
}
tsayen
источник
2
Спасибо за решение! Была небольшая ошибка .... вы дважды установили ширину для thead, и я обнаружил, что вычитание 1.05em из ширины выравнивается немного лучше: jsfiddle.net/xuvsncr2/170
TigerBear
1
как насчет содержимого номера символа? это портит при добавлении большего количества символов или слов в ячейки строки
Limon
Я думаю, что установление некоторой подходящей политики упаковки tdдолжно помочь
tsayen
Любое решение, подобное этому, но отпадает необходимость в ширине 100%?
Александр Перейра Нуньес
2
@tsayen Как вы мешаете ему скручиваться и перекрываться при изменении размера окна?
clearshot66
31

В современных браузерах вы можете просто использовать css:

th {
  position: sticky;
  top: 0;
  z-index: 2;
}
гаусс
источник
8
Это заклинание неполное ... Хотите опубликовать пример или хотя бы разработать?
Лиам
работает хорошо, но относится только к го. Если мы установим позицию на thead, то это не сработает.
Вишал
Исправлено thead должен добавить в W3C!
sonichy
2
Этот ответ работает , когда вы обернуть <table>с <div>которой имеет overflow-y: auto;и некоторые max-height. Например:<div style="overflow-y: auto; max-height: 400px;"><table>...</table></div>
Minwork
Начиная с 2020 года, это будет выбранный ответ (вместе с обновлением @Minwork)
Кристоф Видаль
18

Я использую display:blockдля theadи tbody. Из-за этого ширина theadстолбцов отличается от ширины tbodyстолбцов.

table {
    margin:0 auto; 
    border-collapse:collapse;
}
thead {
    background:#CCCCCC;
    display:block
}
tbody {
    height:10em;overflow-y:scroll;
    display:block
}

Чтобы исправить это, я использую небольшой jQueryкод, но это можно сделать JavaScriptтолько в.

var colNumber=3 //number of table columns    

for (var i=0; i<colNumber; i++) {
  var thWidth=$("#myTable").find("th:eq("+i+")").width();
  var tdWidth=$("#myTable").find("td:eq("+i+")").width();      
  if (thWidth<tdWidth)                    
      $("#myTable").find("th:eq("+i+")").width(tdWidth);
  else
      $("#myTable").find("td:eq("+i+")").width(thWidth);           
}  

Вот мое рабочее демо: http://jsfiddle.net/gavroche/N7LEF/

Не работает в IE 8

Гаврош
источник
Это лучшее / простое решение, которое я нашел, которое допускает нефиксированную ширину столбцов (например, элемент управления .NET DataGrid). Для «производства» colNumberпеременная может быть заменена кодом, который выполняет итерацию по фактическим найденным ячейкам, и обратите внимание, что она не справляется правильно, если есть какие-либо colspan(может быть также улучшена в коде, если необходимо, но вряд ли для вида таблица, вероятно, захочет эту функцию прокрутки).
JonBrave
Это работает (в моде), но не справляется, когда размер окна меньше размера таблицы (так как игнорируется ширина полосы прокрутки).
Ушел кодирование
Да, заголовок и ячейки больше не совпадают, если ширина таблицы ограничена заданной шириной
Крейг,
лучший ответ здесь, самый простой тоже
Чарльз Okwuagwu
18

CSS-только

для Chrome, Firefox, Edge (и других вечнозеленых браузеров)

Просто position: sticky; top: 0;ваши thэлементы:

/* Fix table head */
.tableFixHead    { overflow-y: auto; height: 100px; }
.tableFixHead th { position: sticky; top: 0; }

/* Just common table stuff. */
table  { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 16px; }
th     { background:#eee; }
<div class="tableFixHead">
  <table>
    <thead>
      <tr><th>TH 1</th><th>TH 2</th></tr>
    </thead>
    <tbody>
      <tr><td>A1</td><td>A2</td></tr>
      <tr><td>B1</td><td>B2</td></tr>
      <tr><td>C1</td><td>C2</td></tr>
      <tr><td>D1</td><td>D2</td></tr>
      <tr><td>E1</td><td>E2</td></tr>
    </tbody>
  </table>
</div>

PS: если вам нужны границы для элементов TH, то th {box-shadow: 1px 1px 0 #000; border-top: 0;}это поможет (так как границы по умолчанию не отображаются правильно при прокрутке).

Для варианта вышеупомянутого, который использует только немного JS, чтобы приспособиться к IE11, посмотрите этот ответ https://stackoverflow.com/a/47923622/383904

Роко С. Бульян
источник
Если у вас есть границы для элементов th, использование «border-collapse: collapse» прикрепит границу к телу, а не к заголовку. Чтобы избежать этой проблемы, вы должны использовать «border-collapse: Отдельный». См stackoverflow.com/a/53559396
mrod
@mrod при использовании separateвы добавляете масло в огонь. jsfiddle.net/RokoCB/o0zL4xyw и посмотрите решение ЗДЕСЬ: добавьте границы к фиксированному TH - я приветствую предложения OFC, если я что-то пропустил.
Roko C. Buljan
11

Создайте две таблицы одну за другой, поместите вторую таблицу в div с фиксированной высотой и установите для свойства overflow значение auto. Также держите все td внутри thead во втором столе пустыми.

<div>
    <table>
        <thead>
            <tr>
                <th>Head 1</th>
                <th>Head 2</th>
                <th>Head 3</th>
                <th>Head 4</th>
                <th>Head 5</th>
            </tr>
        </thead>
    </table>
</div>

<div style="max-height:500px;overflow:auto;">
    <table>
        <thead>
            <tr>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody>
        <tr>
            <td>Content 1</td>
            <td>Content 2</td>
            <td>Content 3</td>
            <td>Content 4</td>
            <td>Content 5</td>
        </tr>
        </tbody>
    </table>    
</div>
Сушил Кумар
источник
8
В этом случае столбцы второй таблицы не могут следовать ширине первой таблицы.
kat1330
2
Фигово! Вы потеряете синхронизацию ширины для столбцов в двух таблицах.
Зафар
1
чтобы завершить это решение, нам нужно добавить скрипт @Hashem Qolami ( опишите выше ), чтобы синхронизировать ширину столбцов заголовка
Эльхай Авичзер,
6

Наконец-то я понял это правильно с помощью чистого CSS, выполнив следующие инструкции:

http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/

Первым шагом является установка <tbody>блока display: таким образом, чтобы можно было применить переполнение и высоту. Оттуда строки <thead>необходимо установить в положение: относительное и отображение: блок, чтобы они располагались поверх прокручиваемой теперь <tbody>.

tbody, thead { display: block; overflow-y: auto; }

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

td:nth-child(1), th:nth-child(1) { width: 100px; }
td:nth-child(2), th:nth-child(2) { width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

Но, к сожалению, этого недостаточно. Когда полоса прокрутки присутствует, браузеры выделяют для нее пространство, поэтому в <tbody>итоге получается меньше доступного пространства, чем <thead>. Обратите внимание на небольшое смещение, которое это создает ...

Единственный обходной путь, который я мог придумать, - это установить минимальную ширину для всех столбцов, кроме последнего.

td:nth-child(1), th:nth-child(1) { min-width: 100px; }
td:nth-child(2), th:nth-child(2) { min-width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

Весь пример codepen ниже:

CSS:

.fixed_headers {
  width: 750px;
  table-layout: fixed;
  border-collapse: collapse;
}
.fixed_headers th {
  text-decoration: underline;
}
.fixed_headers th,
.fixed_headers td {
  padding: 5px;
  text-align: left;
}
.fixed_headers td:nth-child(1),
.fixed_headers th:nth-child(1) {
  min-width: 200px;
}
.fixed_headers td:nth-child(2),
.fixed_headers th:nth-child(2) {
  min-width: 200px;
}
.fixed_headers td:nth-child(3),
.fixed_headers th:nth-child(3) {
  width: 350px;
}
.fixed_headers thead {
  background-color: #333333;
  color: #fdfdfd;
}
.fixed_headers thead tr {
  display: block;
  position: relative;
}
.fixed_headers tbody {
  display: block;
  overflow: auto;
  width: 100%;
  height: 300px;
}
.fixed_headers tbody tr:nth-child(even) {
  background-color: #dddddd;
}
.old_ie_wrapper {
  height: 300px;
  width: 750px;
  overflow-x: hidden;
  overflow-y: auto;
}
.old_ie_wrapper tbody {
  height: auto;
}

Html:

<!-- IE < 10 does not like giving a tbody a height.  The workaround here applies the scrolling to a wrapped <div>. -->
<!--[if lte IE 9]>
<div class="old_ie_wrapper">
<!--<![endif]-->

<table class="fixed_headers">
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Plum</td>
      <td>Purple</td>
      <td>These are Purple</td>
    </tr>
    <tr>
      <td>Watermelon</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Tomato</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cherry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cantelope</td>
      <td>Orange</td>
      <td>These are orange inside.</td>
    </tr>
    <tr>
      <td>Honeydew</td>
      <td>Green</td>
      <td>These are green inside.</td>
    </tr>
    <tr>
      <td>Papaya</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Raspberry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Blueberry</td>
      <td>Blue</td>
      <td>These are blue.</td>
    </tr>
    <tr>
      <td>Mango</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Passion Fruit</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

<!--[if lte IE 9]>
</div>
<!--<![endif]-->

РЕДАКТИРОВАТЬ: Альтернативное решение для ширины таблицы 100% (выше на самом деле для фиксированной ширины и не ответил на вопрос):

HTML:

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

CSS:

table {
  width: 100%;
  text-align: left;
  min-width: 610px;
}
tr {
  height: 30px;
  padding-top: 10px
}
tbody { 
  height: 150px; 
  overflow-y: auto;
  overflow-x: hidden;
}
th,td,tr,thead,tbody { display: block; }
td,th { float: left; }
td:nth-child(1),
th:nth-child(1) {
  width: 20%;
}
td:nth-child(2),
th:nth-child(2) {
  width: 20%;
  float: left;
}
td:nth-child(3),
th:nth-child(3) {
  width: 59%;
  float: left;
}
/* some colors */
thead {
  background-color: #333333;
  color: #fdfdfd;
}
table tbody tr:nth-child(even) {
  background-color: #dddddd;
}

Демо: http://codepen.io/anon/pen/bNJeLO

Микаэль Леписто
источник
1
Вопрос, в частности, требовал таблицы шириной 100%, что является единственной вещью, на которую пример, на который вы ссылались , не работает .
Ушел кодирование
@TrueBlueAussie Хороший улов: D Добавлено альтернативное решение для 100% ширины.
Микаэль Леписто
вы не учитываете долготу содержимого ряда ячеек
Лимон
2

Обходной путь Css для принудительного отображения столбцов с помощью 'block' tbody

Это решение все еще требует, чтобы thширина была рассчитана и установлена ​​jQuery

table.scroll tbody,
table.scroll thead { display: block; }

table.scroll tbody {
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 300px;
}

table.scroll tr {
    display: flex;
}

table.scroll tr > td {
    flex-grow: 1;
    flex-basis: 0;
}

И Jquery / Javascript

var $table = $('#the_table_element'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

$table.addClass('scroll');

// Adjust the width of thead cells when window resizes
$(window).resize(function () {

    // Get the tbody columns width array
    colWidth = $bodyCells.map(function () {
        return $(this).width();
    }).get();

    // Set the width of thead columns
    $table.find('thead tr').children().each(function (i, v) {
        $(v).width(colWidth[i]);
    });

}).resize(); // Trigger resize handler
Эммануэль
источник
@ Крэйг в 2019 году, совершенно нормально не заботиться о IE вообще.
Automagisch
2

попробуйте подход ниже, очень просто, легко реализовать

Ниже ссылка jsfiddle

http://jsfiddle.net/v2t2k8ke/2/

HTML:

<table border='1' id='tbl_cnt'>
<thead><tr></tr></thead><tbody></tbody>

CSS:

 #tbl_cnt{
 border-collapse: collapse; width: 100%;word-break:break-all;
 }
 #tbl_cnt thead, #tbl_cnt tbody{
 display: block;
 }
 #tbl_cnt thead tr{
 background-color: #8C8787; text-align: center;width:100%;display:block;
 }
 #tbl_cnt tbody {
 height: 100px;overflow-y: auto;overflow-x: hidden;
 }

Jquery:

 var data = [
    {
    "status":"moving","vehno":"tr544","loc":"bng","dri":"ttt"
    }, {
    "status":"stop","vehno":"tr54","loc":"che", "dri":"ttt"
    },{    "status":"idle","vehno":"yy5499999999999994","loc":"bng","dri":"ttt"
    },{
    "status":"moving","vehno":"tr544","loc":"bng", "dri":"ttt"
    }, {
    "status":"stop","vehno":"tr54","loc":"che","dri":"ttt"
    },{
    "status":"idle","vehno":"yy544","loc":"bng","dri":"ttt"
    }
    ];
   var sth = '';
   $.each(data[0], function (key, value) {
     sth += '<td>' + key + '</td>';
   });
   var stb = '';        
   $.each(data, function (key, value) {
       stb += '<tr>';
       $.each(value, function (key, value) {
       stb += '<td>' + value + '</td>';
       });
       stb += '</tr>';
    });
      $('#tbl_cnt thead tr').append(sth);
      $('#tbl_cnt tbody').append(stb);
      setTimeout(function () {
      var col_cnt=0 
      $.each(data[0], function (key, value) {col_cnt++;});    
      $('#tbl_cnt thead tr').css('width', ($("#tbl_cnt tbody") [0].scrollWidth)+ 'px');
      $('#tbl_cnt thead tr td,#tbl_cnt tbody tr td').css('width',  ($('#tbl_cnt thead tr ').width()/Number(col_cnt)) + 'px');}, 100)
Нанда
источник
2
Это решение не справляется с тем, чтобы окно было уже ширины стола. Это должно включить горизонтальную прокрутку, когда это произойдет. Также заголовки не совпадают точно с ячейками данных (Chrome).
Ушел кодирование
Это не работает в настоящее время
MrHIDEn
2

Добавление фиксированной ширины к td, th после того, как блок tbody & thead работает отлично, а также мы можем использовать плагин slimscroll, чтобы сделать полосу прокрутки красивой.

введите описание изображения здесь

<!DOCTYPE html>
<html>

<head>
    <title> Scrollable table </title>
    <style>
        body {
            font-family: sans-serif;
            font-size: 0.9em;
        }
        table {
            border-collapse: collapse;
            border-bottom: 1px solid #ddd;
        }
        thead {
            background-color: #333;
            color: #fff;
        }
        thead,tbody {
            display: block;
        }
        th,td {
            padding: 8px 10px;
            border: 1px solid #ddd;
            width: 117px;
            box-sizing: border-box;
        }
        tbody {
            height: 160px;
            overflow-y: scroll
        }
    </style>
</head>

<body>

    <table class="example-table">
        <thead>
            <tr>
                <th> Header 1 </th>
                <th> Header 2 </th>
                <th> Header 3 </th>
                <th> Header 4 </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td> Row 1- Col 1 </td>
                <td> Row 1- Col 2 </td>
                <td> Row 1- Col 3 </td>
                <td> Row 1- Col 4 </td>
            </tr>
            <tr>
                <td> Row 2- Col 1 </td>
                <td> Row 2- Col 2 </td>
                <td> Row 2- Col 3 </td>
                <td> Row 2- Col 4 </td>
            </tr>
            <tr>
                <td> Row 3- Col 1 </td>
                <td> Row 3- Col 2 </td>
                <td> Row 3- Col 3 </td>
                <td> Row 3- Col 4 </td>
            </tr>
            <tr>
                <td> Row 4- Col 1 </td>
                <td> Row 4- Col 2 </td>
                <td> Row 4- Col 3 </td>
                <td> Row 4- Col 4 </td>
            </tr>
            <tr>
                <td> Row 5- Col 1 </td>
                <td> Row 5- Col 2 </td>
                <td> Row 5- Col 3 </td>
                <td> Row 5- Col 4 </td>
            </tr>
            <tr>
                <td> Row 6- Col 1 </td>
                <td> Row 6- Col 2 </td>
                <td> Row 6- Col 3 </td>
                <td> Row 6- Col 4 </td>
            </tr>
            <tr>
                <td> Row 7- Col 1 </td>
                <td> Row 7- Col 2 </td>
                <td> Row 7- Col 3 </td>
                <td> Row 7- Col 4 </td>
            </tr>
            <tr>
                <td> Row 8- Col 1 </td>
                <td> Row 8- Col 2 </td>
                <td> Row 8- Col 3 </td>
                <td> Row 8- Col 4 </td>
            </tr>
            <tr>
                <td> Row 9- Col 1 </td>
                <td> Row 9- Col 2 </td>
                <td> Row 9- Col 3 </td>
                <td> Row 9- Col 4 </td>
            </tr>
            <tr>
                <td> Row 10- Col 1 </td>
                <td> Row 10- Col 2 </td>
                <td> Row 10- Col 3 </td>
                <td> Row 10- Col 4 </td>
            </tr>
            <tr>
                <td> Row 11- Col 1 </td>
                <td> Row 11- Col 2 </td>
                <td> Row 11- Col 3 </td>
                <td> Row 11- Col 4 </td>
            </tr>
            <tr>
                <td> Row 12- Col 1 </td>
                <td> Row 12- Col 2 </td>
                <td> Row 12- Col 3 </td>
                <td> Row 12- Col 4 </td>
            </tr>
            <tr>
                <td> Row 13- Col 1 </td>
                <td> Row 13- Col 2 </td>
                <td> Row 13- Col 3 </td>
                <td> Row 13- Col 4 </td>
            </tr>
            <tr>
                <td> Row 14- Col 1 </td>
                <td> Row 14- Col 2 </td>
                <td> Row 14- Col 3 </td>
                <td> Row 14- Col 4 </td>
            </tr>
            <tr>
                <td> Row 15- Col 1 </td>
                <td> Row 15- Col 2 </td>
                <td> Row 15- Col 3 </td>
                <td> Row 15- Col 4 </td>
            </tr>
            <tr>
                <td> Row 16- Col 1 </td>
                <td> Row 16- Col 2 </td>
                <td> Row 16- Col 3 </td>
                <td> Row 16- Col 4 </td>
            </tr>
        </tbody>
    </table>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-slimScroll/1.3.8/jquery.slimscroll.min.js"></script>
    <script>
        $('.example-table tbody').slimscroll({
            height: '160px',
            alwaysVisible: true,
            color: '#333'
        })
    </script>
</body>

</html>

codegeek
источник
1

Вот код, который работает для меня, чтобы создать липкую игру на столе с прокручиваемым телом:

table ,tr td{
    border:1px solid red
}
tbody {
    display:block;
    height:50px;
    overflow:auto;
}
thead, tbody tr {
    display:table;
    width:100%;
    table-layout:fixed;/* even columns width , fix width of table too*/
}
thead {
    width: calc( 100% - 1em )/* scrollbar is average 1em/16px width, remove it from thead width */
}
table {
    width:400px;
}
Макс Александр Ханна
источник
1

Для использования «overflow: scroll» вы должны установить «display: block» на thead и tbody. И это портит ширину столбцов между ними. Но затем вы можете клонировать строку thead с Javascript и вставить ее в tbody как скрытый ряд, чтобы сохранить точную ширину col.

$('.myTable thead > tr').clone().appendTo('.myTable tbody').addClass('hidden-to-set-col-widths');

http://jsfiddle.net/Julesezaar/mup0c5hk/

<table class="myTable">
    <thead>
        <tr>
            <td>Problem</td>
            <td>Solution</td>
            <td>blah</td>
            <td>derp</td>
        </tr>
    </thead>
    <tbody></tbody>
</table>
<p>
  Some text to here
</p>

CSS:

table {
  background-color: #aaa;
  width: 100%;
}

thead,
tbody {
  display: block; // Necessary to use overflow: scroll
}

tbody {
  background-color: #ddd;
  height: 150px;
  overflow-y: scroll;
}

tbody tr.hidden-to-set-col-widths,
tbody tr.hidden-to-set-col-widths td {
  visibility: hidden;
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
}

td {
  padding: 3px 10px;
}
Julesezaar
источник
0

Попробуйте это jsfiddle . Это использует jQuery и сделано из ответа Хашема Колами. Сначала создайте обычную таблицу, затем сделайте ее прокручиваемой.

const makeScrollableTable = function (tableSelector, tbodyHeight) {
  let $table = $(tableSelector);
  let $bodyCells = $table.find('tbody tr:first').children();
  let $headCells = $table.find('thead tr:first').children();
  let headColWidth = 0;
  let bodyColWidth = 0;

  headColWidth = $headCells.map(function () {
    return $(this).outerWidth();
  }).get();
  bodyColWidth = $bodyCells.map(function () {
    return $(this).outerWidth();
  }).get();

  $table.find('thead tr').children().each(function (i, v) {
    $(v).css("width", headColWidth[i]+"px");
    $(v).css("min-width", headColWidth[i]+"px");
    $(v).css("max-width", headColWidth[i]+"px");
  });
  $table.find('tbody tr').children().each(function (i, v) {
    $(v).css("width", bodyColWidth[i]+"px");
    $(v).css("min-width", bodyColWidth[i]+"px");
    $(v).css("max-width", bodyColWidth[i]+"px");
  });

  $table.find('thead').css("display", "block");
  $table.find('tbody').css("display", "block");

  $table.find('tbody').css("height", tbodyHeight+"px");
  $table.find('tbody').css("overflow-y", "auto");
  $table.find('tbody').css("overflow-x", "hidden");

};
LeChat
источник