Таблиця з фіксованим заголовком та фіксованою колонкою на чистому css


97

Мені потрібно створити HTML-таблицю (або щось схоже на вигляд) з фіксованим заголовком і фіксованим першим стовпцем.

Кожне рішення, яке я бачив до цього часу, використовує Javascript або jQueryдля встановлення scrollTop / scrollLeft, але воно не працює гладко в мобільних браузерах, тому я шукаю чистого рішення CSS.

Тут я знайшов рішення для фіксованого стовпця: jsfiddle.net/C8Dtf/20/, але я не знаю, як я можу його покращити, щоб заголовок теж фіксувався.

Я хочу, щоб він працював у браузерах webkit або використовував деякі css3функції, але повторюю, я не хочу використовувати Javascriptдля прокрутки.

EDIT: Це приклад поведінки, яку я хочу досягти: https://web.archive.org/web/20130829032141/http://datatables.net/release-datatables/extras/FixedColumns/css_size.html


Я не бачу, де на даний момент <html> <table> з фіксованим заголовком <thead> має відношення до css-level-3. Що ще у вас є? Що ви пробували поки що?
Мілче Патерн,

Я намагався застосувати складну positionповедінку до рядків і комірок, але не зовсім розумію, де це підлягає чи ні.
panfil

2
Ця відповідь може допомогти вам stackoverflow.com/questions/14834198/…
Гаррі

Відповіді:


141

Фактичне рішення CSS із фіксованим рядком заголовка та першим стовпцем

Мені довелося створити таблицю як з фіксованим заголовком, так і з фіксованим першим стовпцем, використовуючи чистий CSS, і жодна з відповідей тут була зовсім не такою, яку я хотів.

position: stickyВластивість підтримує як прилипання до вершини (як я бачив , як це використовується самий) і в бік в сучасних версіях Chrome, Firefox, і Edge. Це можна поєднати з тим, divщо маєoverflow: scroll властивість давати вам таблицю з фіксованими заголовками, які можна розмістити де завгодно на вашій сторінці:

Помістіть свій стіл у контейнер:

<div class="container">
  <table></table>
</div>

Використовуйте overflow: scrollна своєму контейнері, щоб увімкнути прокрутку:

div.container {
  overflow: scroll;
}

Як в коментарях зазначив Дагмар , контейнеру також потрібні а max-widthі а max-height.

Використовуйте , position: stickyщоб осередки таблиць прилипають до краю і top, rightабо , leftщоб вибрати , який край дотримуватися:

thead th {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;
}

tbody th {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 0;
}

Як зазначав MarredCheese у коментарях, якщо ваш перший стовпець містить <td>елементи замість <th>елементів, ви можете використовувати tbody td:first-childу своєму CSS замістьtbody th

Щоб заголовок у першій колонці прилипав ліворуч, використовуйте:

thead th:first-child {
  left: 0;
  z-index: 1;
}

https://jsfiddle.net/qwubvg9m/1/


22
Це здається найкращою відповіддю.
user1190132

9
@PirateApp Якщо вам відомий widthваш перший стовпець, ви можете використовувати position: stickyв комірках у другому стовпці leftзначення, рівне першому стовпцю width: jsfiddle.net/wvypo83c/794
Matthew Schlachter

4
Ця відповідь доводить, що варто її читати до кінця!
mlerley

4
Це не працює без встановленої на контейнері максимальної ширини та максимальної висоти.
Дагмар

9
Ця відповідь є маяком, що веде нас додому через нескінченне море несправних, надскладних, витрачаючих часу відповідей на диво-впевнені, здивовано схвалені плакати тут, на просторах та в Інтернеті. Зверніть увагу, що якщо ваш перший стовпець містить <td>елементи замість <th>елементів, ви можете використовувати tbody td:first-childу своєму CSS замість tbody th.
MarredCheese

33

Сьогодні це можливо досягти, використовуючи CSS лише з position: stickyвластивістю.

Ось фрагмент:

(jsFiddle: https://jsfiddle.net/hbqzdzdt/5/ )

.grid-container {
  display: grid; /* This is a (hacky) way to make the .grid element size to fit its content */
  overflow: auto;
  height: 300px;
  width: 600px;
}
.grid {
  display: flex;
  flex-wrap: nowrap;
}
.grid-col {
  width: 150px;
  min-width: 150px;
}

.grid-item--header {
  height: 100px;
  min-height: 100px;
  position: sticky;
  position: -webkit-sticky;
  background: white;
  top: 0;
}

.grid-col--fixed-left {
  position: sticky;
  left: 0;
  z-index: 9998;
  background: white;
}
.grid-col--fixed-right {
  position: sticky;
  right: 0;
  z-index: 9998;
  background: white;
}

.grid-item {
  height: 50px;
  border: 1px solid gray;
}
<div class="grid-container">
  <div class="grid">
    <div class="grid-col grid-col--fixed-left">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col grid-col--fixed-right">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
    </div>

  </div>
</div>

Щодо сумісності. Він працює у всіх основних браузерах, але не в IE. Існує поліфіл для, position: stickyале я його ніколи не пробував.


2
Це чудово, любіть це!
Капітан Лу

3
будь-яким способом досягти цього за допомогою <table> -тегів, а не <div>
Андреас

1
Я думаю, що це не матиме хорошої продуктивності, якщо ви розробляєте додаток і вам потрібно провести цикл записів, щоб надрукувати цю таблицю, оскільки для кожного стовпця таблиці ви повинні пройти цикл через весь масив записів. Цей HTML працює по колонці.
igasparetto

@igasparetto Ви можете насправді розташувати рядки / стовпці навпаки, і рішення все одно буде працювати. Якщо у мене буде трохи пізніше, я можу створити фрагмент із впорядкованою сіткою рядком -> стовпець.
Альваро

2
Я б радив не відображати табличні дані без використання <table> та пов'язаних тегів. Є кілька проблем із порушенням цільового використання HTML таким чином, включаючи доступність. Дивіться також: w3.org/WAI/tutorials/tables
Бен Морріс,

15

Це нелегкий подвиг.

Наступне посилання стосується робочої демонстрації:

Посилання оновлено відповідно до коментаря lanoxx

http://jsfiddle.net/C8Dtf/366/

Просто не забудьте додати такі:

<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/extras/FixedColumns/media/js/FixedColumns.js"></script>

я не бачу іншого шляху досягнення цього. Особливо не за допомогою лише css.

Це багато, що потрібно пережити. Сподіваюся, це допомагає :)


Для перемикання фільтра використовуйте: "bFilter": false
lanoxx

6
Це є можливим досягти цього лише з допомогою CSS. Непросто, але можливо.
Jimmy T.

з приблизно 10 рішень це працювало єдине. До речі, видалити "bInfo" : false.dataTable()
доданий

datatables == "awesome"
billynoah

проголосувавши за це рішення, оскільки воно погане. theadв своїй таблиці , яка не пов'язана із змінами tdелементів, так що якщо текст клітина довга, thширина не корегуватиме відповідним чином .
vsync

14

Всі ці пропозиції є чудовими, але вони або виправляють лише заголовок або стовпець, а не обидва, або використовують javascript. Причина - вона не вірить, що це можна зробити в чистому CSS. Причина:

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

Чудово. Але зараз проблема - ви можете змусити одного з них залишатися на місці, коли ви прокручуєте, але інший вкладений всередину області прокрутки першого і тому може прокручуватися поза полем зору, тому його неможливо зафіксувати на місці на екран. "А-ха", скажете ви, "але я можу якось використовувати абсолютне або фіксоване положення для цього" - ні, ви не можете. Як тільки ви це зробите, ви втратите можливість прокручувати цей контейнер. Це ситуація з куркою та яйцем - у вас не може бути обох, вони скасовують один одного.

Я вважаю, що єдине рішення - через javascript. Вам потрібно повністю відокремити три елементи та синхронізувати їх позиції за допомогою JavaScript. Є хороші приклади в інших публікаціях на цій сторінці. Це також варто подивитися:

http://tympanus.net/codrops/2014/01/09/sticky-table-headers-columns/


9

Я вніс деякі зміни в jsfiddle. Це може бути те, що ви намагаєтесь зробити.

http://jsfiddle.net/C8Dtf/81/

Я чітко кодував назви так:

<table id="left_table" class="freeze_table">
    <tr class='tblTitle'>
         <th>Title 1</th>
         <th>Title 2</th>
    </tr>
</table>

І я також додав кілька стилів.

.tblTitle{
   position:absolute;
    top:0px;
    margin-bottom:30px;
    background:lightblue;
}
td, th{
    padding:5px;
    height:40px;
    width:40px;
    font-size:14px;
}

Сподіваюсь, що ви цього хочете :)


1
Мені потрібен заголовок правильної таблиці, щоб прокрутити разом із її вмістом.
panfil

Ось URL-адреса: jsfiddle.net/C8Dtf/84 . Вам просто потрібно пограти зі стилем для правої таблиці, щоб вирівняти дві таблиці.
Філіп-Хуан,

Ні. Ви не дуже розумієте. Мені потрібно, щоб заголовок правої таблиці був закріплений у верхній частині, щоб він все ще був видимим, коли таблиця прокручується вгору і вниз, але коли таблиця прокручується вправо або вліво, верхній заголовок повинен прокручуватись вправо або вліво, але все одно фіксуватися у верхній частині. Вибачте за мої погані знання англійської мови.
панфіл

Тож хочете, щоб заголовок правої таблиці був зафіксований при вертикальній прокрутці та прокручувався при горизонтальній прокрутці?
Філіп-Хуан,

Це приклад поведінки, якої я хочу досягти: datatables.net/release-datatables/extras/FixedColumns/…
panfil

9

Приклад використання лише CSS:

.table {
  table-layout: fixed;
  width: 500px;
  border-collapse: collapse;
}

.header th {
  font-family: Calibri;
  font-size: small;
  font-weight: lighter;
  border-left: 1px solid #000;
  background: #d0d0d0;
}

.body_panel {
  display: inline-block;
  width: 520px;
  height: 300px;
  overflow-y: scroll;
}

.body tr {
  border-bottom: 1px solid #d0d0d0;
}

.body td {
  border-left: 1px solid #d0d0d0;
  padding-left: 3px;
  font-family: Calibri;
  font-size: small;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
<body>

  <table class="table">

    <thead class="header">

      <tr>
        <th style="width:20%;">teste</th>
        <th style="width:30%;">teste 2</th>
        <th style="width:50%;">teste 3</th>
      </tr>

    </thead>
  </table>

  <div class="body_panel">

    <table class="table">
      <tbody class="body">

        <tr>
          <td style="width:20%;">asbkj k kajsb ksb kabkb</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

      </tbody>
    </table>

  </div>

</body>


3
Мені потрібен був не лише хедер, а й перша колонка.
panfil

Цей приклад показує підхід з двома таблицями в html: одна таблиця відображає лише заголовок; друга таблиця відображає лише рядки, але робить це в межах div. Саме це divдозволяє прокручувати рядки, поки заголовок залишається на тому самому місці. Такий підхід спрацював на мої потреби.
Девід Тансі

Якщо є також горизонтальна прокрутка, вам потрібен JS для синхронізації позицій прокрутки таблиць.
Золтан Тамасі

4

Щоб виправити заголовки та стовпці, ви можете скористатися наступним плагіном:


Оновлено в липні 2019 року

Нещодавно з'явилося також чисте рішення CSS, яке базується на властивості CSS position: sticky;( тут для отримання додаткової інформації про нього), застосованому до кожного THелемента (замість батьківського контейнера)


1
Перше посилання порушено. У другому використовується jQuery.
PussInBoots

Оновлена ​​відповідь про видалення мертвого посилання
Luca Detomi

3

Я знайшов чудове рішення Пола О'Браєна щодо проблеми, і хотів би поділитися посиланням: https://codepen.io/paulobrien/pen/LBrMxa

Я видалив стиль для нижнього колонтитулу:

html {
  box-sizing: border-box;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
.intro {
  max-width: 1280px;
  margin: 1em auto;
}
.table-scroll {
  position: relative;
  width:100%;
  z-index: 1;
  margin: auto;
  overflow: auto;
  height: 350px;
}
.table-scroll table {
  width: 100%;
  min-width: 1280px;
  margin: auto;
  border-collapse: separate;
  border-spacing: 0;
}
.table-wrap {
  position: relative;
}
.table-scroll th,
.table-scroll td {
  padding: 5px 10px;
  border: 1px solid #000;
}
.table-scroll thead th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

th:first-child {
  position: -webkit-sticky;
  position: sticky;
  left: 0;
  z-index: 2;
  background: #ccc;
}
thead th:first-child {
  z-index: 5;
}

2

Нещодавно мені довелося створити рішення із фіксованою групою заголовків та фіксованою першою колоною. Я розділив свою таблицю на діви та використав jquery для зйомки прокрутки вікна.

http://jsfiddle.net/TinT/EzXub/2346/

var prevTop = 0;
var prevLeft = 0;

$(window).scroll(function(event){
  var currentTop = $(this).scrollTop();
  var currentLeft = $(this).scrollLeft();

  if(prevLeft !== currentLeft) {
    prevLeft = currentLeft;
    $('.header').css({'left': -$(this).scrollLeft()})
  }
  if(prevTop !== currentTop) {
    prevTop = currentTop;
    $('.leftCol').css({'top': -$(this).scrollTop() + 40})
  }
});

1

Ми з колегою щойно випустили новий проект GitHub, який постачає директиву Angular, за допомогою якої ви можете прикрасити свій стіл фіксованими заголовками: https://github.com/objectcomputing/FixedHeader

Він покладається лише на css та angular, з директивою, яка додає деякі знаки. Не потрібно jQuery.

Ця реалізація не така повнофункціональна, як деякі інші реалізації, але якщо вам потрібно просто додати фіксовані таблиці, ми вважаємо, що це може бути хорошим варіантом.


1

Після двох днів боротьби з Internet Explorer 9 + Chrome + Firefox (Windows) та Safari (Mac), я знайшов систему, яка

  • Сумісний з усіма цими браузерами
  • Без використання JavaScript
  • Використовуючи лише une div та одну таблицю
  • Фіксований заголовок і колонтитул (крім IE), з тілом, що прокручується. Заголовок і тіло з однаковою шириною стовпця

Результат: введіть тут опис зображення

HTML:

  <thead>
    <tr>
      <th class="nombre"><%= f.label :cost_center %></th>
      <th class="cabecera cc">Personal</th>
      <th class="cabecera cc">Dpto</th>
    </tr>
  </thead>
  <tbody>
    <% @cost_centers.each do |cc| %>
    <tr>
      <td class="nombre"><%= cc.nombre_corto %></td>
      <td class="cc"><%= cc.cacentrocoste %></td>
      <td class="cc"><%= cc.cacentrocoste_dpto %></td>
    </tr>
    <% end %>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="3"><a href="#">Mostrar mas usuarios</a></td>
    </tr>
  </tfoot>
</table>

CSS:

div.cost_center{
  width:320px;
  font-size:75%;
  margin-left:5px;
  margin-top:5px;
  margin-bottom: 2px;
  float: right;
  display: inline-block;
  overflow-y: auto;
  overflow-x: hidden;
  max-height:300px;  
}

div.cost_center label { 
  float:none;
  font-size:14px;
}

div.cost_center table{
  width:300px;
  border-collapse: collapse; 
  float:right;
  table-layout:fixed;
}

div.cost_center table tr{
  height:16px;
}
div.cost_center th{
  font-weight:normal;
}

div.cost_center table tbody{
  display: block;
  overflow: auto;
  max-height:240px;
}

div.cost_center table thead{
  display:block;
}

div.cost_center table tfoot{
  display:block;
}
div.cost_center table tfoot td{
  width:280px;
}
div.cost_center .cc{
  width:60px;
  text-align: center; 
  border: 1px solid #999;
}

div.cost_center .nombre{
  width:150px;
}
div.cost_center tbody .nombre{
  border: 1px solid #999;
}

div.cost_center table tfoot td{
 text-align:center;  
 border: 1px solid #999; 
} 

div.cost_center table th, 
div.cost_center table td { 
  padding: 2px;
  vertical-align: middle; 
}

div.cost_center table tbody td {
  white-space: normal;
  font:  .8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: white;
}
div.cost_center table th.cabecera { 
  font:  0.8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: #FFEAB5;
}

Хороша спроба, але для мене це працює не надто добре. У цьому прикладі ( jsfiddle.net/5ka6e ) заголовок змінюється неправильно. Помилка такого типу могла з часом призвести до невідповідності даних та заголовків.
darkzangel

1
Ви забуваєте додати, div.cost_center table{border-collapse: collapse;}і третій підпис повинен бути таким, що підходить до 60 пікселів (у цьому прикладі)
Альберт Катала

1

Існуючі відповіді підійдуть більшості людей, але тим, хто хоче додати тіні під зафіксованим заголовком та праворуч від першого (фіксованого) стовпця, ось робочий приклад (чистий css):

http://jsbin.com/nayifepaxo/1/edit?html,output

Основний фокус, щоб змусити це працювати, - ::afterце додавання тіней праворуч від кожного з перших tdу кожному tr:

tr td:first-child:after {
  box-shadow: 15px 0 15px -15px rgba(0, 0, 0, 0.05) inset;
  content: "";
  position:absolute;
  top:0;
  bottom:0;
  right:-15px;
  width:15px;
}

Зайняв мене деякий час (занадто довго ...), щоб все це працювало, тому я зрозумів, що поділюсь із тими, хто опинився в подібній ситуації.


Ви базували це на будь-якій іншій відповіді та додали тінь?
PussInBoots

1

потрібно виправити нижній колонтитул заголовка


0

Щось подібне може підійти вам ... Можливо, вам знадобиться встановити ширину стовпців для рядка заголовка.

thead { 
    position: fixed;
}

http://jsfiddle.net/vkhNC/

Оновлення:

Я не впевнений, що наведений вами приклад можливий лише за допомогою CSS. Я хотів би, щоб хтось довів, що я не правий. Ось те, що я маю на сьогодні . Це не готовий продукт, але це може бути початком для вас. Сподіваюсь, це вказує вам на корисний напрямок, де б це не було.


Мені потрібен не лише заголовок, але і перший стовпець, також виправлений.
панфіл

5
Проблема полягає в тому, що заголовки втрачають свою ширину. Це виглядає некрасиво з різним розміром стовпця заголовка та розміром стовпця даних.
Akash Kava

0

Іншим рішенням є використання AngularJS. Модуль AngularUI має директиву з назвою, ng-gridяка підтримує функцію, яка називається закріпленням стовпців. Це не 100% чистий CSS, але не є й іншими рішеннями.

http://angular-ui.github.io/ng-grid/#columnPinning


0

Приклад чистого CSS:

<div id="cntnr">
    <div class="tableHeader">
        <table class="table-header table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>


    <div class="tableBody">
        <table class="table-body table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>

</div>

#cntnr {
    width: auto;
    height: 200px;
    border: solid 1px #444;
    overflow: auto;
}

.tableHeader {
    position: fixed;
    height: 40px;
    overflow: hidden;
    margin-right: 18px;
    background: white;
}

.table-header tbody {
    height: 0;
    visibility: hidden;
}

.table-body thead {
    height: 0;
    visibility: hidden;
}

http://jsfiddle.net/cCarlson/L98m854d/

Недолік: Фіксована структура / логіка заголовка досить залежить від конкретних розмірів, тому абстракція, ймовірно, не є життєздатним варіантом .


Потрібні як фіксований заголовок, так і фіксований перший стовпець.
panfil

Ах ... байдуже, що ти вказав на це, панфіле. Я зроблю редагування. Вітання
Коді

0

Позиція: липкий не працює для деяких елементів, таких як (thead) у chrome та інших браузерах webkit, таких як сафарі.

Але це добре працює з (м)

body {
  background-color: rgba(0, 255, 200, 0.1);
}

.intro {
  color: rgb(228, 23, 23);
}

.wrapper {
  overflow-y: scroll;
  height: 300px;
}

.sticky {
  position: sticky;
  top: 0;
  color: black;
  background-color: white;
}
<div class="container intro">
  <h1>Sticky Table Header</h1>
  <p>Postion : sticky doesn't work for some elements like (thead) in chrome and other webkit browsers like safari. </p>
  <p>But it works fine with (th)</p>
</div>
<div class="container wrapper">
  <table class="table table-striped">
    <thead>
      <tr>
        <th class="sticky">Firstname</th>
        <th class="sticky">Lastname</th>
        <th class="sticky">Email</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>James</td>
        <td>Vince</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Jonny</td>
        <td>Bairstow</td>
        <td>jonny@example.com</td>
      </tr>
      <tr>
        <td>James</td>
        <td>Anderson</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Stuart</td>
        <td>Broad</td>
        <td>stuart@example.com</td>
      </tr>
      <tr>
        <td>Eoin</td>
        <td>Morgan</td>
        <td>eoin@example.com</td>
      </tr>
      <tr>
        <td>Joe</td>
        <td>Root</td>
        <td>joe@example.com</td>
      </tr>
      <tr>
        <td>Chris</td>
        <td>Woakes</td>
        <td>chris@example.com</td>
      </tr>
      <tr>
        <td>Liam</td>
        <td>PLunkett</td>
        <td>liam@example.com</td>
      </tr>
      <tr>
        <td>Jason</td>
        <td>Roy</td>
        <td>jason@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Hales</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Jos</td>
        <td>Buttler</td>
        <td>jos@example.com</td>
      </tr>
      <tr>
        <td>Ben</td>
        <td>Stokes</td>
        <td>ben@example.com</td>
      </tr>
      <tr>
        <td>Jofra</td>
        <td>Archer</td>
        <td>jofra@example.com</td>
      </tr>
      <tr>
        <td>Mitchell</td>
        <td>Starc</td>
        <td>mitchell@example.com</td>
      </tr>
      <tr>
        <td>Aaron</td>
        <td>Finch</td>
        <td>aaron@example.com</td>
      </tr>
      <tr>
        <td>David</td>
        <td>Warner</td>
        <td>david@example.com</td>
      </tr>
      <tr>
        <td>Steve</td>
        <td>Smith</td>
        <td>steve@example.com</td>
      </tr>
      <tr>
        <td>Glenn</td>
        <td>Maxwell</td>
        <td>glenn@example.com</td>
      </tr>
      <tr>
        <td>Marcus</td>
        <td>Stoinis</td>
        <td>marcus@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Carey</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Nathan</td>
        <td>Coulter Nile</td>
        <td>nathan@example.com</td>
      </tr>
      <tr>
        <td>Pat</td>
        <td>Cummins</td>
        <td>pat@example.com</td>
      </tr>
      <tr>
        <td>Adam</td>
        <td>Zampa</td>
        <td>zampa@example.com</td>
      </tr>
    </tbody>
  </table>
</div>

Або відвідайте мій приклад codepen :


-1

Я думаю, що це допоможе вам: https://datatables.net/release-datatables/extensions/FixedHeader/examples/header_footer.html

Якщо коротко, якщо ви знаєте, як створити таблицю даних, вам просто потрібно додати цей рядок jQuery до вашого кінця:

$(document).ready(function() {
    var table = $('#example').DataTable();

    new $.fn.dataTable.FixedHeader( table, {
        bottom: true
    } );
} );

bottom: true // також для фіксації заголовка Bottom.


-2

Якщо ви хочете використовувати лише чистий HTML та CSS, у мене є рішення для вашої проблеми:
У цьому jsFiddle ви можете побачити рішення без сценарію, яке забезпечує таблицю з фіксованим заголовком. Не повинно бути проблемою також адаптувати розмітку для фіксованого першого стовпця. Вам просто потрібно буде створити таблицю з абсолютним розташуванням для першого стовпця всередині hWrapper-div та змінити позицію vWrapper-div.
Надання динамічного контенту не повинно бути проблемою при використанні спокусників на стороні сервера або браузера, моє рішення добре працює у всіх сучасних браузерах та старих браузерах, починаючи з IE8 і далі.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.