Как создать таблицу HTML с фиксированным / замороженным левым столбцом и прокручиваемым телом?


267

Мне нужно простое решение. Я знаю, что это похоже на некоторые другие вопросы, такие как:

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


Очень хорошая реализация (на мой взгляд) размещена здесь: stackoverflow.com/a/57524791
Джон Джон

Для нескольких строк, заблокированных с несколькими столбцами, см. Stackoverflow.com/questions/53332830
Абель Каллехо

Ответы:


379

Если вам нужна таблица, в которой только столбцы прокручиваются горизонтально, вы можете position: absoluteвыбрать первый столбец (и указать его ширину явно), а затем обернуть всю таблицу в overflow-x: scroll блок. Не пытайтесь попробовать это в IE7, однако ...

Соответствующие HTML и CSS:

table {
  border-collapse: separate;
  border-spacing: 0;
  border-top: 1px solid grey;
}

td, th {
  margin: 0;
  border: 1px solid grey;
  white-space: nowrap;
  border-top-width: 0px;
}

div {
  width: 500px;
  overflow-x: scroll;
  margin-left: 5em;
  overflow-y: visible;
  padding: 0;
}

.headcol {
  position: absolute;
  width: 5em;
  left: 0;
  top: auto;
  border-top-width: 1px;
  /*only relevant for first row*/
  margin-top: -1px;
  /*compensate for top border*/
}

.headcol:before {
  content: 'Row ';
}

.long {
  background: yellow;
  letter-spacing: 1em;
}
<div>
<table>
        <tr><th class="headcol">1</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">2</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">3</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">4</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">5</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
        <tr><th class="headcol">6</th><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td><td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td></tr>
</table>
</div>

скрипка


31
Это не обрабатывает произвольные метки. Если у вас нет очень предсказуемо коротких ярлыков, вы получите это: jsfiddle.net/YMvk9/3724
AaronLS

8
@AaronLS: да, вам нужно указать ширину первого столбца. Если вам нужно иметь дело с метками произвольной длины, вы можете использовать их text-overflow: ellipsisдля точного отображения.
Имон Нербонн

14
@EamonNerbonne ellipsis был хорошим вариантом, который я рассмотрел. Другим вариантом было сделать что-то вроде этого. Повторение первого столбца скрыто, а также исправлено. Второй скрытый столбец обеспечивает высоту синхронизации строк. Работает, только если у вас есть столбец фиксированной ширины: jsfiddle.net/abkNM/2224
AaronLS

4
Для тех, кто заинтересован. По сути, решение убирает заголовки со стола и устанавливает для каждого из них ширину 5em. Сам стол сдвинут вправо на ту же ширину 5em. Это создает визуальное представление о том, что заголовки все еще являются частью обычного потока в таблице.
HelloWorld

4
Вот небольшой пример без лишнего кода jsfiddle.net/kashesandr/rLv5b1ft/1
kashesandr

26

Это интересный плагин jQuery, который создает фиксированные заголовки и / или столбцы . Переключите фиксированный столбец на true на демо-странице, чтобы увидеть его в действии.


1
это для строк, а не столбцов
Fortega

4
@Fortega: это также для столбцов, если вы установите свойство fixedColumn: true. Есть демо, которое вы можете проверить.
Маркос Фрагкакис

ну хорошо, это было не ясно. Демо не работало на прошлой неделе. Но это сейчас.
Fortega

1
@ Thomas1703 Вы должны использовать плагин Migrate из jQuery, если плагин не работает с 1.9.x -> jquery.com/download
321X

4
Этот плагин очень медленно работает с большими таблицами.
A1rPun

26

Вы можете использовать stickyположение. Вот пример кода. Это решение HTML / CSS. Нет JS не требуется.

.view {
  margin: auto;
  width: 600px;
}

.wrapper {
  position: relative;
  overflow: auto;
  border: 1px solid black;
  white-space: nowrap;
}

.sticky-col {
  position: sticky;
  position: -webkit-sticky;
  background-color: white;
}

.first-col {
  width: 100px;
  min-width: 100px;
  max-width: 100px;
  left: 0px;
}

.second-col {
  width: 150px;
  min-width: 150px;
  max-width: 150px;
  left: 100px;
}
<div class="view">
  <div class="wrapper">
    <table class="table">
      <thead>
        <tr>
          <th class="sticky-col first-col">Number</th>
          <th class="sticky-col second-col">First Name</th>
          <th>Last Name</th>
          <th>Employer</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td class="sticky-col first-col">1</td>
          <td class="sticky-col second-col">Mark</td>
          <td>Ham</td>
          <td>Micro</td>
        </tr>
        <tr>
          <td class="sticky-col first-col">2</td>
          <td class="sticky-col second-col">Jacob</td>
          <td>Smith</td>
          <td>Adob Adob Adob AdobAdob Adob Adob Adob Adob</td>
        </tr>
        <tr>
          <td class="sticky-col first-col">3</td>
          <td class="sticky-col second-col">Larry</td>
          <td>Wen</td>
          <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

Загрузочный код: https://www.bootply.com/g8pfBXOcY9


1
Конечно, это самый простой и логичный способ сделать это, я сделал только: $ ("table th: first"). Css ("position", "sticky"). Css ("left", "0px") .css ("background-color", $ ("body"). css ("background-color")); и в цикле для каждого ряда, и это было все!
Деян Дозет

Это должен быть принятый ответ. Нет позиции: абсолютный размер взлома и размеры ячеек таблицы не фиксированы.
Феликс Лемке

можно ли сделать только 1 столбец липким? Я пробую вашу ссылку, но я не могу это сделать? Как будто я хочу сделать колонку работодателя липкой
Муним Хабиб

@MuneemHabib Если вы хотите, чтобы только первый столбец был липким, посмотрите это
Автоматический выключатель

19

В случае фиксированной ширины левой колонки лучшее решение предлагает Имон Нербонн .

В случае левой ширины столбца с переменной шириной лучшее решение, которое я нашел, состоит в том, чтобы создать две одинаковые таблицы и толкать их друг над другом. Демо: http://jsfiddle.net/xG5QH/6/ .

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
/* important styles */

.container {
   /* Attach fixed-th-table to this container,
      in order to layout fixed-th-table
      in the same way as scolled-td-table" */
   position: relative;

   /* Truncate fixed-th-table */
   overflow: hidden;
}

.fixed-th-table-wrapper td,
.fixed-th-table-wrapper th,
.scrolled-td-table-wrapper td,
.scrolled-td-table-wrapper th {
   /* Set background to non-transparent color
      because two tables are one above another.
    */
   background: white;
}
.fixed-th-table-wrapper {
   /* Make table out of flow */
   position: absolute;
}
.fixed-th-table-wrapper th {
    /* Place fixed-th-table th-cells above 
       scrolled-td-table td-cells.
     */
    position: relative;
    z-index: 1;
}
.scrolled-td-table-wrapper td {
    /* Place scrolled-td-table td-cells
       above fixed-th-table.
     */
    position: relative;
}
.scrolled-td-table-wrapper {
   /* Make horizonal scrollbar if needed */
   overflow-x: auto;
}


/* Simulating border-collapse: collapse,
   because fixed-th-table borders
   are below ".scrolling-td-wrapper table" borders
*/

table {
    border-spacing: 0;
}
td, th {
   border-style: solid;
   border-color: black;
   border-width: 1px 1px 0 0;
}
th:first-child {
   border-left-width: 1px;
}
tr:last-child td,
tr:last-child th {
   border-bottom-width: 1px;
}

/* Unimportant styles */

.container {
    width: 250px;
}
td, th {
   padding: 5px;
}
</style>
</head>

<body>
<div class="container">

<div class="fixed-th-table-wrapper">
<!-- fixed-th-table -->
<table>
    <tr>
         <th>aaaaaaa</th>
         <td>ccccccccccc asdsad asd as</td>
         <td>ccccccccccc asdsad asd as</td>
    </tr>
    <tr>
         <th>cccccccc</th>
         <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
         <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
    </tr>
</table>
</div>

<div class="scrolled-td-table-wrapper">
<!-- scrolled-td-table
     - same as fixed-th-table -->
<table>
    <tr>
         <th>aaaaaaa</th>
         <td>ccccccccccc asdsad asd as</td>
         <td>ccccccccccc asdsad asd as</td>
    </tr>
    <tr>
         <th>cccccccc</th>
         <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
         <td>xxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyy zzzzzzzzzzzzz</td>
    </tr>
</table>
</div>

</div>
</body>
</html>

1
+10 очень умно. Пришлось установить границу коллапса seperateпод загрузкой, в противном случае границы не плавают вместе с клетками. После этого требуется очистка границы.
Патрик

Очень хорошо! Спасибо! я не использовал <th> по своим собственным причинам, я использовал класс, чтобы указать, какой столбец должен быть исправлен, и, для хорошей меры, добавил a visibility: collapse; к столбцам, чтобы скрыть их от фиксированной таблицы (должен полюбить :not()селектор css! ). я также использовал jQuery для .clone()таблицы, как только он был сгенерирован php + MySQL + ajax, и вставил его в очищенный div ...
Peter

17

FWIW, вот таблица с возможностью прокрутки с фиксированной головой и стороной.

http://codepen.io/ajkochanowicz/pen/KHdih


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

Это решение также не перегружает браузер большими таблицами, с чем, вероятно, вам придется иметь дело, если вам нужны фиксированные заголовки / столбцы.
Адам Роу

1
@AdamGrant это хорошо. Ширина ячеек должна быть фиксированной, чтобы охватить все случаи, но я могу уйти с этим;)
Мирко

@ Flipbed: В любом случае вы должны исправить ширину ячеек. Настоящая проблема в том, что высота тоже фиксирована. Просто очень плохо. Мне нужно решение с переменной высотой.
Стефан Штайгер

14

Немного поздно, но я наткнулся на эту тему, когда пробовал решения для себя. Предполагая, что вы используете современные браузеры в настоящее время, я предложил решение, использующее CSS calc (), чтобы гарантировать соответствие ширины.

.table-fixed-left table,
.table-fixed-right table {
  border-collapse: collapse;
}
.table-fixed-right td,
.table-fixed-right th,
.table-fixed-left td,
.table-fixed-left th {
  border: 1px solid #ddd;
  padding: 5px 5px;
}
.table-fixed-left {
  width: 120px;
  float: left;
  position: fixed;
  overflow-x: scroll;
  white-space: nowrap;
  text-align: left;
  border: 1px solid #ddd;
  z-index: 2;
}
.table-fixed-right {
  width: calc(100% - 145px);
  right: 15px;
  position: fixed;
  overflow-x: scroll;
  border: 1px solid #ddd;
  white-space: nowrap;
}
.table-fixed-right td,
.table-fixed-right th {
  padding: 5px 10px;
}
<div class="table-fixed-left">
  <table>
    <tr>
      <th>Normal Header</th>
    </tr>
    <tr>
      <th>Header with extra line
        <br/>&nbsp;</th>
    </tr>
    <tr>
      <th>Normal Header</th>
    </tr>
    <tr>
      <th>Normal with extra line
        <br/>&nbsp;</th>
    </tr>
    <tr>
      <th>Normal Header</th>
    </tr>
    <tr>
      <th>Normal Header</th>
    </tr>
  </table>
</div>
<div class="table-fixed-right">
  <table>
    <tr>
      <th>Header</th>
      <th>Another header</th>
      <th>Header</th>
      <th>Header really really really really long</th>
    </tr>
    <tr>
      <td>Info Long</td>
      <td>Info
        <br/>with second line</td>
      <td>Info
        <br/>with second line</td>
      <td>Info Long</td>
    </tr>
    <tr>
      <td>Info Long</td>
      <td>Info Long</td>
      <td>Info Long</td>
      <td>Info Long</td>
    </tr>
    <tr>
      <td>Info
        <br/>with second line</td>
      <td>Info
        <br/>with second line</td>
      <td>Info
        <br/>with second line</td>
      <td>Info</td>
    </tr>
    <tr>
      <td>Info</td>
      <td>Info</td>
      <td>Info</td>
      <td>Info</td>
    </tr>
    <tr>
      <td>Info</td>
      <td>Info</td>
      <td>Info</td>
      <td>Info</td>
    </tr>
  </table>
</div>

Надеюсь, это поможет кому-то!


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

Какова идея с <br/>&nbsp;в <th>элементе?
Серхио

после решения многих проблем css с принятым ответом, это решение разделения двух таблиц звучит как лучшее решение
Ayyash

11

Стиль левой колонки с position: fixed. (Вы , вероятно хотите использовать topи leftстили , чтобы контролировать , где именно это происходит.)


2
Это блестяще в своей простоте. Можно ли разрешить правильную вертикальную прокрутку всей страницы?
agsamek

Да; Вы должны пропустить всю часть «таблицы» и просто использовать два div, один для левого столбца и один для остальной части содержимого. Div левого столбца получает position: fixedи остается на месте, остальная часть содержимого работает нормально (предположительно с установленным левым полем, чтобы он не перекрывал левый столбец).
хаос

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

11

Для большинства браузеров, выпущенных после 2017 года:

Вы можете использовать position: sticky. Смотрите https://caniuse.com/#feat=css-sticky .

Нет необходимости в столбце фиксированной ширины.

Запустите фрагмент кода ниже, чтобы увидеть, как он работает.

.tscroll {
  width: 400px;
  overflow-x: scroll;
  margin-bottom: 10px;
  border: solid black 1px;
}

.tscroll table td:first-child {
  position: sticky;
  left: 0;
  background-color: #ddd;
}

.tscroll td, .tscroll th {
  border-bottom: dashed #888 1px;
}
<html>
<div class="tscroll">
  <table>
    <thead>
      <tr>
        <th></th>
        <th colspan="5">Heading 1</th>
        <th colspan="8">Heading 2</th>
        <th colspan="4">Heading 3</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>9:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
      <tr>
        <td>10:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
      <tr>
        <td>11:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
      <tr>
        <td>12:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
      <tr>
        <td>13:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
      <tr>
        <td>14:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
      <tr>
        <td>15:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
      <tr>
        <td>16:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
      <tr>
        <td>17:00</td>
        <td>AAA</td>
        <td>BBB</td>
        <td>CCC</td>
        <td>DDD</td>
        <td>EEE</td>
        <td>FFF</td>
        <td>GGG</td>
        <td>HHH</td>
        <td>III</td>
        <td>JJJ</td>
        <td>KKK</td>
        <td>LLL</td>
        <td>MMM</td>
        <td>NNN</td>
        <td>OOO</td>
        <td>PPP</td>
        <td>QQQ</td>
      </tr>
    </tbody>
    </table>
</div>


2
Уже существует ответ на предложение sticky , поэтому нет необходимости в один более
Асон

1
@LGSon Я не согласен, были только два других ответа, используя липкий. Одним из них является использование начальной загрузки CSS для реализации липкой. Другой ответ содержит код, не связанный напрямую с вопросом, неверный и использует фиксированную ширину для закрепленного столбца.
kojow7

1
Независимо от того, используете ли вы Bootstrap, а другой - фиксируете ширину, position: stickyего поведение не меняется, поэтому его использование уже было показано.
Асон

8

Я взял ответ Earmon Nerbonne и отредактировал его для работы с таблицами, которые занимают всю ширину.

http://jsfiddle.net/DYgD6/6/

<!DOCTYPE html>
<html><head><title>testdoc</title>
<style type="text/css">
            body {
        font:16px Calibri;
    }
    table {
        border-collapse:separate;
        border-top: 3px solid grey;
    }
    td {
        margin:0;
        border:3px solid grey;
        border-top-width:0px;
        white-space:nowrap;
    }
    #outerdiv {
        position: absolute;
        top: 0;
        left: 0;
        right: 5em;
    }
    #innerdiv {
        width: 100%;
        overflow-x:scroll;
        margin-left: 5em;
        overflow-y:visible;
        padding-bottom:1px;
    }
    .headcol {
        position:absolute;
        width:5em;
        left:0;
        top:auto;
        border-right: 0px none black;
        border-top-width:3px;
        /*only relevant for first row*/
        margin-top:-3px;
        /*compensate for top border*/
    }
    .headcol:before {
        content:'Row ';
    }
    .long {
        background:yellow;
        letter-spacing:1em;
    }
</style></head><body>
  <div id="outerdiv">
   <div id="innerdiv">
    <table>
        <tr>
            <td class="headcol">1</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
        <tr>
            <td class="headcol">2</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
        <tr>
            <td class="headcol">3</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
        <tr>
            <td class="headcol">4</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
        <tr>
            <td class="headcol">5</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
        <tr>
            <td class="headcol">6</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
        <tr>
            <td class="headcol">7</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
        <tr>
            <td class="headcol">8</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
        <tr>
            <td class="headcol">9</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
        </tr>
    </table>
</div></div>
</body></html>

Ширина фиксированного столбца все еще должна быть заданным значением.


7

Если вы разрабатываете что-то более сложное и хотите, чтобы несколько столбцов были зафиксированы / закреплены слева, вам, вероятно, понадобится нечто подобное.

.wrapper {
    overflow-x: scroll;
}

td {
    min-width: 50px;
}

.fixed {
    position: absolute;
    background: #aaa;
}
<div class="content" style="width: 400px">

  <div class="wrapper" style="margin-left: 100px">

      <table>
        <thead>
          <tr>
            <th class="fixed" style="left: 0px">aaa</th>
            <th class="fixed" style="left: 50px">aaa2</th>
            <th>a</th>
            <th>b</th>
            <th>c</th>
            <th>d</th>
            <th>e</th>
            <th>f</th>
            <th>a</th>
            <th>b</th>
            <th>c</th>
            <th>d</th>
            <th>e</th>
            <th>f</th>
            <th>a</th>
            <th>b</th>
            <th>c</th>
            <th>d</th>
            <th>e</th>
            <th>f</th>
            <th>a</th>
            <th>b</th>
            <th>c</th>
            <th>d</th>
            <th>e</th>
            <th>f</th>        
          </tr>
        </thead>
        <tbody>
          <tr>
            <td class="fixed" style="left: 0px">aaa</td>
            <td class="fixed" style="left: 50px">aaa2</td>
            <td>a</td>
            <td>b</td>
            <td>c</td>
            <td>d</td>
            <td>e</td>
            <td>f</td>
            <td>a</td>
            <td>b</td>
            <td>c</td>
            <td>d</td>
            <td>e</td>
            <td>f</td>
            <td>a</td>
            <td>b</td>
            <td>c</td>
            <td>d</td>
            <td>e</td>
            <td>f</td>
            <td>a</td>
            <td>b</td>
            <td>c</td>
            <td>d</td>
            <td>e</td>
            <td>f</td>
          </tr>
          <tr>
            <td class="fixed" style="left: 0">bbb</td>
            <td class="fixed" style="left: 50px">bbb2</td>
            <td>a</td>
            <td>b</td>
            <td>c</td>
            <td>d</td>
            <td>e</td>
            <td>f</td>
            <td>a</td>
            <td>b</td>
            <td>c</td>
            <td>d</td>
            <td>e</td>
            <td>f</td>
            <td>a</td>
            <td>b</td>
            <td>c</td>
            <td>d</td>
            <td>e</td>
            <td>f</td>
            <td>a</td>
            <td>b</td>
            <td>c</td>
            <td>d</td>
            <td>e</td>
            <td>f</td>
          </tr>
        </tbody>
      </table>

  </div>

</div>


2
Это прекрасно работает, но как я могу установить фиксированную высоту для таблицы?
Хуан Камило Мехия

3

Если вы находитесь в аду Webdevelopper и вам нужно, чтобы это работало для IE6, вот пример кода, который я использовал:

<html>
<head>
<style type="text/css">
.fixme {
    position: relative;
    left: expression( ( 20 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
    background-color: #FFFFFF;
}
</style>
</head>
<body>
<table width="1500px" border="2">
    <tr>
        <td class="fixme" style="width: 200px;">loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet</td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
    </tr>
    <tr>
        <td class="fixme" style="width: 200px;">loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
    </tr>
    <tr>
        <td class="fixme" style="width: 200px;">loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
    </tr>
    <tr>
        <td class="fixme" style="width: 200px;">loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
        <td>loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet loremp ispum dolor sit amet </td>
    </tr>
</table>
</body>
</html>

Это будет работать, вероятно, ТОЛЬКО для IE6, поэтому используйте условные комментарии для CSS.


2

Не нужно добавлять плагин, CSS может сделать эту работу !!!

Идея состоит в том, чтобы сделать положение всех первых ячеек в каждом столбце абсолютным и сделать ширину фиксированной. Пример:

max-width: 125px;
min-width: 125px;
position: absolute;

Это скрывает некоторые части некоторых столбцов под первым столбцом, поэтому добавьте пустой второй столбец (добавьте второй пустой тд) с шириной, равной ширине первого столбца.

Я тестировал, и это работает в Chrome и Firefox.


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

Не могли бы вы привести пример?
kashesandr

2

Имон Нербонн, я изменил некоторые CSS в вашем коде, и теперь стало лучше (полоса прокрутки начинается с первого ряда)

http://jsfiddle.net/At8L8/

Я просто добавляю две строки:

.div : padding-left:5em;
.headcol : background-color : #fff;

Подскажите, пожалуйста, как вы получили полосу прокрутки из замороженной колонки? Также влияет ли изменение <th> на <td>?
Себу Элиас

2

Вы можете просто сделать первый столбец position: sticky; z-index: 9. Это сделает столбец / строку придерживаться своей текущей позиции. Проверьте мой пример codepen здесь https://codepen.io/swastikmishra/pen/zYYdKBQ

Пример HTML

<style type="text/css">
            table{ text-align: center; }
            .table-container{ width: 500px; height: 300px; overflow: scroll;}
            table th, table td {
                white-space: nowrap;
                padding: 10px 20px;
                font-family: Arial;
            }
            table tr th:first-child, table td:first-child{
                position: sticky;
                width: 100px;
                left: 0;
                z-index: 10;
                background: #fff;
            }
            table tr th:first-child{
                z-index: 11;
            }
            table tr th{
                position: sticky;
                top: 0;
                z-index: 9;
                background: #fff;
            }
        </style>
        <div class="table-container">
            <table>
                <tr><th>Hello World</th><th>Hello World</th><th>Hello World</th><th>Hello World</th><th>Hello World</th><th>Hello World</th><th>Hello World</th></tr>
                <tr><td>H11</td><td>H12</td><td>H13</td><td>H14</td><td>H15</td><td>H16</td><td>H17</td></tr>
                <tr><td>H21</td><td>H22</td><td>H23</td><td>H24</td><td>H25</td><td>H26</td><td>H27</td></tr>
                <tr><td>H31</td><td>H32</td><td>H33</td><td>H34</td><td>H35</td><td>H36</td><td>H37</td></tr>
                <tr><td>H41</td><td>H42</td><td>H44</td><td>H44</td><td>H45</td><td>H46</td><td>H47</td></tr>
                <tr><td>H51</td><td>H52</td><td>H54</td><td>H54</td><td>H55</td><td>H56</td><td>H57</td></tr>
                <tr><td>H61</td><td>H62</td><td>H64</td><td>H64</td><td>H65</td><td>H66</td><td>H67</td></tr>
                <tr><td>H71</td><td>H72</td><td>H74</td><td>H74</td><td>H75</td><td>H76</td><td>H77</td></tr>
                <tr><td>H81</td><td>H82</td><td>H84</td><td>H84</td><td>H85</td><td>H86</td><td>H87</td></tr>
            </table>
        </div>

1

Опера глючила во всех предыдущих ответах, когда я проверял их на своем Mac. Если вы прокрутите таблицу, фиксированный столбец исчезнет после прохождения первого нефиксированного столбца. Я пошел дальше и написал код ниже. Он работает во всех браузерах, которые я установил локально. Я не знаю, как то есть, то есть.

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

<table class = "fixedColumns">
    <tr><td> row 1 </td></tr>
    <tr><td> row 2 </td></tr>
</table>
<table class = "scrollableTable">
    <tr><td> col 1 </td> <td> col 2 </td><td> col 3 </td><td> col 4 </td></tr>
    <tr><td> col 1 </td> <td> col 2 </td><td> col 3 </td><td> col 4 </td></tr>
</table>

<style type = "text/css" >
    .fixedColumns
    {
        vertical-align:top;
        display: inline-block;
    }
    .scrollableTable
    {
        display: inline-block;
        width:50px;
        white-space: nowrap;
        overflow-x: scroll;
    }
</style>

1

Вот еще одна модификация самого популярного ответа, но с обработкой переменной длины текста в метках первого столбца: http://jsfiddle.net/ozx56n41/

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

HTML:

<div id="outerdiv">
    <div id="innerdiv">
        <table>
            <tr>
                <td class="headcol"><div>This is a long label</div></td>
                <td class="hiddenheadcol"><div>This is a long label</div></td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
            <tr>
                <td class="headcol"><div>Short label</div></td>
                <td class="hiddenheadcol"><div>Short label</div></td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
                <td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
            </tr>
        </table>
    </div>
</div>

CSS:

body {
    font: 16px Calibri;
}
#outerdiv {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    border-top: 1px solid grey;
}
#innerdiv {
    overflow-x: scroll;
    margin-left: 100px;
    overflow-y: visible;
    padding-bottom: 1px;
}
table {
    border-collapse:separate;
}
td {
    margin: 0;
    border: 1px solid grey;
    border-top-width: 0;
    border-left-width: 0px;
    padding: 10px;
}
td.headcol {
    /* Frozen 1st column */
    position: absolute;
    left: 0;
    top: auto;
    border-bottom-width: 1px;
    padding: 0;
    border-left-width: 1px;
}
td.hiddenheadcol {
    /* Hidden 2nd column to create height */
    max-width: 0;
    visibility: hidden;
    padding: 0;
}
td.headcol div {
    /* Text container in the 1st column */
    width: 100px;
    max-width: 100px;
    background: lightblue;
    padding: 10px;
    box-sizing: border-box;
}
td.hiddenheadcol div {
    /* Text container in the 2nd column */
    width: 100px;
    max-width: 100px;
    background: red;
    padding: 10px;
}
td.long {
    background:yellow;
    letter-spacing:1em;
}

1

Для меня это был единственный, который работал отлично (спасибо Полу О'Брайену!): Https://codepen.io/paulobrien/pen/gWoVzN

Вот фрагмент:

// requires jquery library
jQuery(document).ready(function() {
  jQuery(".main-table").clone(true).appendTo('#table-scroll').addClass('clone');   
 });
  .table-scroll {
    position:relative;
    max-width:600px;
    margin:auto;
    overflow:hidden;
    border:1px solid #000;
  }
.table-wrap {
	width:100%;
	overflow:auto;
}
.table-scroll table {
	width:100%;
	margin:auto;
	border-collapse:separate;
	border-spacing:0;
}
.table-scroll th, .table-scroll td {
	padding:5px 10px;
	border:1px solid #000;
	background:#fff;
	white-space:nowrap;
	vertical-align:top;
}
.table-scroll thead, .table-scroll tfoot {
	background:#f9f9f9;
}
.clone {
	position:absolute;
	top:0;
	left:0;
	pointer-events:none;
}
.clone th, .clone td {
	visibility:hidden
}
.clone td, .clone th {
	border-color:transparent
}
.clone tbody th {
	visibility:visible;
	color:red;
}
.clone .fixed-side {
	border:1px solid #000;
	background:#eee;
	visibility:visible;
}
.clone thead, .clone tfoot{background:transparent;}
<div id="table-scroll" class="table-scroll">
  <div class="table-wrap">
    <table class="main-table">
      <thead>
        <tr>
          <th class="fixed-side" scope="col">&nbsp;</th>
          <th scope="col">Header 2</th>
          <th scope="col">Header 3</th>
          <th scope="col">Header 4</th>
          <th scope="col">Header 5</th>
          <th scope="col">Header 6</th>
          <th scope="col">Header 7</th>
          <th scope="col">Header 8</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content<br>
            test</td>
          <td><a href="#">Cell content longer</a></td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
        <tr>
          <th class="fixed-side">Left Column</th>
          <td>Cell content</td>
          <td>Cell content longer</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
          <td>Cell content</td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <th class="fixed-side">&nbsp;</th>
          <td>Footer 2</td>
          <td>Footer 3</td>
          <td>Footer 4</td>
          <td>Footer 5</td>
          <td>Footer 6</td>
          <td>Footer 7</td>
          <td>Footer 8</td>
        </tr>
      </tfoot>
    </table>
  </div>
</div>

<p>See <a href="https://codepen.io/paulobrien/pen/LBrMxa" target="blank">position Sticky version </a>with no JS</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>


0

В качестве альтернативы, стиль tbody с заранее заданным размером ( height:20emнапример, через) и использоватьoverflow-y:scroll;

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


Чтобы тело таблицы можно было прокручивать, оно должно отображаться как блок
danielrvt

0
//If the table has tbody and thead, make them the relative container in which we can fix td and th as absolute

table tbody {
    position: relative;
}

table thead {
    position: relative;
}

//Make both the first header and first data cells (First column) absolute so that it sticks to the left

table td:first-of-type {
    position: absolute;
}

table th:first-of-type {
    position: absolute;
}

//Move Second column according to the width of column 1 

table td:nth-of-type(2) {
    padding-left: <Width of column 1>;
}

table th:nth-of-type(2) {
    padding-left: <Width of column 1>;
}

0

$(document).ready(function() {
    var table = $('#example').DataTable( {
        scrollY:        "400px",
        scrollX:        true,
        scrollCollapse: true,
        paging:         true,
        fixedColumns:   {
            leftColumns: 3
        }
    } );
} );
<head>
	<title>table</title>
	
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/fixedcolumns/3.2.4/css/fixedColumns.dataTables.min.css">
<script type="text/javascript" src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/fixedcolumns/3.2.4/js/dataTables.fixedColumns.min.js"></script>


<style>
       th, td { white-space: nowrap; }
    div.dataTables_wrapper {
        width: 900px;
        margin: 0 auto;
    }
</style>

</head>
<table id="example" class="stripe row-border order-column" style="width:100%">
        <thead>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
                <th>Extn.</th>
                <th>E-mail</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Tiger</td>
                <td>Nixon</td>
                <td>System Architect</td>
                <td>Edinburgh</td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$320,800</td>
                <td>5421</td>
                <td>t.nixon@datatables.net</td>
            </tr>
            <tr>
                <td>Garrett</td>
                <td>Winters</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
                <td>8422</td>
                <td>g.winters@datatables.net</td>
            </tr>
            <tr>
                <td>Ashton</td>
                <td>Cox</td>
                <td>Junior Technical Author</td>
                <td>San Francisco</td>
                <td>66</td>
                <td>2009/01/12</td>
                <td>$86,000</td>
                <td>1562</td>
                <td>a.cox@datatables.net</td>
            </tr>
            <tr>
                <td>Cedric</td>
                <td>Kelly</td>
                <td>Senior Javascript Developer</td>
                <td>Edinburgh</td>
                <td>22</td>
                <td>2012/03/29</td>
                <td>$433,060</td>
                <td>6224</td>
                <td>c.kelly@datatables.net</td>
            </tr>
            <tr>
                <td>Airi</td>
                <td>Satou</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>33</td>
                <td>2008/11/28</td>
                <td>$162,700</td>
                <td>5407</td>
                <td>a.satou@datatables.net</td>
            </tr>
            <tr>
                <td>Brielle</td>
                <td>Williamson</td>
                <td>Integration Specialist</td>
                <td>New York</td>
                <td>61</td>
                <td>2012/12/02</td>
                <td>$372,000</td>
                <td>4804</td>
                <td>b.williamson@datatables.net</td>
            </tr>
            <tr>
                <td>Herrod</td>
                <td>Chandler</td>
                <td>Sales Assistant</td>
                <td>San Francisco</td>
                <td>59</td>
                <td>2012/08/06</td>
                <td>$137,500</td>
                <td>9608</td>
                <td>h.chandler@datatables.net</td>
            </tr>
            <tr>
                <td>Rhona</td>
                <td>Davidson</td>
                <td>Integration Specialist</td>
                <td>Tokyo</td>
                <td>55</td>
                <td>2010/10/14</td>
                <td>$327,900</td>
                <td>6200</td>
                <td>r.davidson@datatables.net</td>
            </tr>
            <tr>
                <td>Colleen</td>
                <td>Hurst</td>
                <td>Javascript Developer</td>
                <td>San Francisco</td>
                <td>39</td>
                <td>2009/09/15</td>
                <td>$205,500</td>
                <td>2360</td>
                <td>c.hurst@datatables.net</td>
            </tr>
            <tr>
                <td>Sonya</td>
                <td>Frost</td>
                <td>Software Engineer</td>
                <td>Edinburgh</td>
                <td>23</td>
                <td>2008/12/13</td>
                <td>$103,600</td>
                <td>1667</td>
                <td>s.frost@datatables.net</td>
            </tr>
            <tr>
                <td>Jena</td>
                <td>Gaines</td>
                <td>Office Manager</td>
                <td>London</td>
                <td>30</td>
                <td>2008/12/19</td>
                <td>$90,560</td>
                <td>3814</td>
                <td>j.gaines@datatables.net</td>
            </tr>
             <tr>
                <td>Sakura</td>
                <td>Yamamoto</td>
                <td>Support Engineer</td>
                <td>Tokyo</td>
                <td>37</td>
                <td>2009/08/19</td>
                <td>$139,575</td>
                <td>9383</td>
                <td>s.yamamoto@datatables.net</td>
            </tr>
            <tr>
                <td>Thor</td>
                <td>Walton</td>
                <td>Developer</td>
                <td>New York</td>
                <td>61</td>
                <td>2013/08/11</td>
                <td>$98,540</td>
                <td>8327</td>
                <td>t.walton@datatables.net</td>
            </tr>
            <tr>
                <td>Finn</td>
                <td>Camacho</td>
                <td>Support Engineer</td>
                <td>San Francisco</td>
                <td>47</td>
                <td>2009/07/07</td>
                <td>$87,500</td>
                <td>2927</td>
                <td>f.camacho@datatables.net</td>
            </tr>
            <tr>
                <td>Serge</td>
                <td>Baldwin</td>
                <td>Data Coordinator</td>
                <td>Singapore</td>
                <td>64</td>
                <td>2012/04/09</td>
                <td>$138,575</td>
                <td>8352</td>
                <td>s.baldwin@datatables.net</td>
            </tr>
            <tr>
                <td>Zenaida</td>
                <td>Frank</td>
                <td>Software Engineer</td>
                <td>New York</td>
                <td>63</td>
                <td>2010/01/04</td>
                <td>$125,250</td>
                <td>7439</td>
                <td>z.frank@datatables.net</td>
            </tr>
            <tr>
                <td>Zorita</td>
                <td>Serrano</td>
                <td>Software Engineer</td>
                <td>San Francisco</td>
                <td>56</td>
                <td>2012/06/01</td>
                <td>$115,000</td>
                <td>4389</td>
                <td>z.serrano@datatables.net</td>
            </tr>
            <tr>
                <td>Jennifer</td>
                <td>Acosta</td>
                <td>Junior Javascript Developer</td>
                <td>Edinburgh</td>
                <td>43</td>
                <td>2013/02/01</td>
                <td>$75,650</td>
                <td>3431</td>
                <td>j.acosta@datatables.net</td>
            </tr>
            <tr>
                <td>Cara</td>
                <td>Stevens</td>
                <td>Sales Assistant</td>
                <td>New York</td>
                <td>46</td>
                <td>2011/12/06</td>
                <td>$145,600</td>
                <td>3990</td>
                <td>c.stevens@datatables.net</td>
            </tr>
            <tr>
                <td>Hermione</td>
                <td>Butler</td>
                <td>Regional Director</td>
                <td>London</td>
                <td>47</td>
                <td>2011/03/21</td>
                <td>$356,250</td>
                <td>1016</td>
                <td>h.butler@datatables.net</td>
            </tr>
            <tr>
                <td>Lael</td>
                <td>Greer</td>
                <td>Systems Administrator</td>
                <td>London</td>
                <td>21</td>
                <td>2009/02/27</td>
                <td>$103,500</td>
                <td>6733</td>
                <td>l.greer@datatables.net</td>
            </tr>
            <tr>
                <td>Jonas</td>
                <td>Alexander</td>
                <td>Developer</td>
                <td>San Francisco</td>
                <td>30</td>
                <td>2010/07/14</td>
                <td>$86,500</td>
                <td>8196</td>
                <td>j.alexander@datatables.net</td>
            </tr>
            <tr>
                <td>Shad</td>
                <td>Decker</td>
                <td>Regional Director</td>
                <td>Edinburgh</td>
                <td>51</td>
                <td>2008/11/13</td>
                <td>$183,000</td>
                <td>6373</td>
                <td>s.decker@datatables.net</td>
            </tr>
            <tr>
                <td>Michael</td>
                <td>Bruce</td>
                <td>Javascript Developer</td>
                <td>Singapore</td>
                <td>29</td>
                <td>2011/06/27</td>
                <td>$183,000</td>
                <td>5384</td>
                <td>m.bruce@datatables.net</td>
            </tr>
            <tr>
                <td>Donna</td>
                <td>Snider</td>
                <td>Customer Support</td>
                <td>New York</td>
                <td>27</td>
                <td>2011/01/25</td>
                <td>$112,000</td>
                <td>4226</td>
                <td>d.snider@datatables.net</td>
            </tr>
        </tbody>
    </table>

Это можно легко сделать с помощью таблиц данных. Люди, которые плохо знакомы с таблицами данных, обращаются к https://datatables.net/. Это плагин и предлагает множество функций. В приведенном коде заголовок исправлен, первые 3 столбца исправлены, а некоторые другие функции также там.


не работает, если вам нужен одновременно и фиксированный столбец, и фиксированный заголовок
PirateApp

0

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

https://codepen.io/kushagrarora/pen/zeYaoY

var freezeTables = document.getElementsByClassName("freeze-pane");

[].forEach.call(freezeTables, ftable => {
  var wrapper = document.createElement("div");
  wrapper.className = "freeze-pane-wrapper";
  var scroll = document.createElement("div");
  scroll.className = "freeze-pane-scroll";

  wrapper.appendChild(scroll);

  ftable.parentNode.replaceChild(wrapper, ftable);

  scroll.appendChild(ftable);

  var heads = ftable.querySelectorAll("th:first-child");

  let maxWidth = 0;

  [].forEach.call(heads, head => {
    var w = window
      .getComputedStyle(head)
      .getPropertyValue("width")
      .split("px")[0];
    if (Number(w) > Number(maxWidth)) maxWidth = w;
  });

  ftable.parentElement.style.marginLeft = maxWidth + "px";
  ftable.parentElement.style.width = "calc(100% - " + maxWidth + "px)";
  [].forEach.call(heads, head => {
    head.style.width = maxWidth + "px";
    var restRowHeight = window
      .getComputedStyle(head.nextElementSibling)
      .getPropertyValue("height");
    var headHeight = window.getComputedStyle(head).getPropertyValue("height");
    if (headHeight > restRowHeight)
      head.nextElementSibling.style.height = headHeight;
    else head.style.height = restRowHeight;
  });
});
@import url("https://fonts.googleapis.com/css?family=Open+Sans");
* {
  font-family: "Open Sans", sans-serif;
}

.container {
  width: 400px;
  height: 90vh;
  border: 1px solid black;
  overflow: hidden;
}

table,
th,
td {
  border: 1px solid #eee;
}

.table {
  width: 100%;
  margin-bottom: 1rem;
  table-layout: fixed;
  border-collapse: collapse;
}

.freeze-pane-wrapper {
  position: relative;
}

.freeze-pane-scroll {
  overflow-x: scroll;
  overflow-y: visible;
}

.freeze-pane th:first-child {
  position: absolute;
  background-color: pink;
  left: 0;
  top: auto;
  max-width: 40%;
}
<div class="container">
  <table class="freeze-pane">
    <tbody>
      <tr>
        <th>
          <p>Model</p>
        </th>
        <th>
          <p>Mercedes Benz AMG C43 4dr</p>
        </th>
        <th>
          <p>Audi S4 Premium 4dr</p>
        </th>
        <th>
          <p>BMW 440i 4dr sedan</p>
        </th>
      </tr>
      <tr>
        <th>
          <p>Passenger capacity</p>
        </th>
        <td>
          <p>5</p>
        </td>
        <td>
          <p>5</p>
        </td>
        <td>
          <p>5</p>
        </td>
      </tr>
      <tr>
        <th>
          <p>Front (Head/Shoulder/Leg) (In.)</p>
        </th>
        <td>
          <p>37.1/55.3/41.7</p>
        </td>
        <td>
          <p>38.9/55.9/41.3</p>
        </td>
        <td>
          <p>39.9/54.8/42.2</p>
        </td>
      </tr>
      <tr>
        <th>
          <p>Second (Head/Shoulder/Leg) (In.)</p>
        </th>
        <td>
          <p>37.1/55.5/35.2</p>
        </td>
        <td>
          <p>37.4/54.5/35.7</p>
        </td>
        <td>
          <p>36.9/54.3/33.7</p>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Примечание: div "container" предназначен для демонстрации совместимости кода с мобильным представлением.


0

Я только что сделал самый правый липкий столбец таблицы липким.

th:last-of-type {
 position: sticky;
 right: 0;
 width: 120px;
 background: #f7f7f7;
}


td:last-of-type {
 position: sticky;
 right: 0;
 background: #f7f7f7;
 width: 120px;
}

Я верю, что если вы это сделаете {position: sticky; left: 0;}, вы получите желаемый результат.


К сожалению sticky, не поддерживается IE.
ГТУ

0

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

В примере показан один из способов сделать это без JS

table {
  border-collapse: collapse;
  border-spacing: 0;
  border: 1px solid #ddd;
  min-width: 600px;
}

.labels {
  display:flex;
  flex-direction: column
}

.overflow {
  overflow-x: scroll;
  min width: 400px;
  flex: 1;
}

.label {
  display: flex;
  align-items: center;
  white-space:nowrap;
  padding: 10px;
  flex: 1;
  border-bottom: 1px solid #ddd;
  border-right: 2px solid #ddd;
}

.label:last-of-type {
  overflow-x: scroll;
  border-bottom: 0;
}

td {
  border: 1px solid #ddd;
  padding: 10px;
}

.flex {
  display:flex;
  max-width: 600px;
  padding: 0;
  border: 5px solid #ddd;
}
<div class="flex">
  <div class="labels">
    <span class="label">Label 1</span>
    <span class="label">Lorem ipsum dolor sit amet.</span>
    <span class="label">Lorem ipsum dolor.</span>
  </div>
  <div class="overflow">
    <table>
      <tr>
        <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
        <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
      </tr>
      <tr>
        <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
        <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
      </tr>
      <tr>
        <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
        <td class="long">Lorem ipsum dolor sit amet consectetur adipisicing</td>
      </tr>
  </table>
  </div>
</div>


-1

В HTML5 вы можете использовать CSS style.transform.
Тем не менее, я рекомендую вам «пролистывать страницы» отключить, если вы реализуете на Mac.

посмотрите на пример codePen

let l  = 0;
let t  = 0;

const MouseWheelHandler = (e) => {
  // vertical scroll
  if (e.deltaX == -0) {
    // t = t - e.deltaY

  // horizonal scroll
  } else if (e.deltaY == -0) {
    l = l - e.deltaX
    if (l >= 0) {
      l = 0;
      document.getElementById("gantt_task").style.transform = "translateX(1px)"
      document.getElementById("gantt_task_header").style.transform = "translateX(1px)"
      return false
    } 
    document.getElementById("gantt_task").style.transform = "translateX(" + l.toString() + "px)"
    document.getElementById("gantt_task_header").style.transform = "translateX(" + l.toString() + "px)"
  }
  return false;
}

window.addEventListener("wheel", MouseWheelHandler, false);
.row {
  border-bottom: 1px solid #979A9A
}
#gantt_grid_header {
  height:   30px;
  width:    100px;
  position: fixed;
  z-index:  3;
  top:      0px;
  left:     0px;
  border:   1px solid #cecece;
  background-color: #F08080;
}     

#gantt_task_header {
  height:   30px;
  width:    400px;
  position: fixed;
  z-index:  2;
  top:      0px;
  left:     100px;
  border:   1px solid #cecece;
  background-color: #FFC300;
}

#gantt_grid {
  width:    100px; 
  height:   400px;
  position: absolute;
  left:     0px;
  top:      0px;
  z-index:  1;
  border:   1px solid #cecece;
  background-color: #DAF7A6;
}

#gantt_task {
  width:    400px; 
  height:   400px;
  position: absolute;
  left:     100px;
  top:      0px;
  border:   1px solid #cecece;
  background-color: #FF5733;
}
<html>
    <div id="gantt_grid_header">
      HEADER
    </div>
    <div id="gantt_grid">
      <div class="row">V Scroll OK</div>
      <div class="row">V Scroll OK</div>
      <div class="row">V Scroll OK</div>
      <div class="row">V Scroll OK</div>
      <div class="row">V Scroll OK</div>
      <div class="row">V Scroll OK</div>
      <div class="row">V Scroll OK</div>
      <div class="row">V Scroll OK</div>
      <div class="row">V Scroll OK</div>
    </div>
    <div id="gantt_task_header">
      DATA HEADER
    </div>
    <div id="gantt_task">
      <div class="row">Vertical,Horizenal Scroll OK</div>
      <div class="row">Vertical,Horizenal Scroll OK</div>
      <div class="row">Vertical,Horizenal Scroll OK</div>
      <div class="row">Vertical,Horizenal Scroll OK</div>
      <div class="row">Vertical,Horizenal Scroll OK</div>
      <div class="row">Vertical,Horizenal Scroll OK</div>
      <div class="row">Vertical,Horizenal Scroll OK</div>
      <div class="row">Vertical,Horizenal Scroll OK</div>
      <div class="row">Vertical,Horizenal Scroll OK</div>
    </div>
</html>


2
В редких случаях пользователи могут отключить функцию ОС для использования вашего веб-сайта.
Натан Артур

-2

Добавьте это в голову:

<link rel="stylesheet" type="text/css" href="/path/to/easyscrolltable.css">
<script src="/path/to/easyscrolltable.js"></script>

Javascript:

$('table.ytable').EasyScrollableTable({
    'top'  : 1,  
    'left' : 1,  
    'class': '',
    'width': '100%',
    'height': 'auto',
    'footer': false,
    'hover': true
});

1
Я попробовал вашу библиотеку, и эта страница больше не отображается, отладчик говорит, что проблема «остановлена ​​до нехватки памяти».
Пьер-Адриен Мезон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.