Как сделать фиксированную таблицу заголовков с таблицей и шириной ячейки в процентах в CSS? [дубликат]

avatar
Pavel_K
8 апреля 2018 в 07:30
15450
7
6

Я нашел следующее решение для фиксированной таблицы заголовков:

table {
  width: 450px;
  border-collapse: collapse;
}

thead {
  display: block;
  width: 450px;
  overflow: auto;
  color: #fff;
  background: #000;
}

tbody {
  display: block;
  width: 450px;
  height: 200px;
  background: pink;
  overflow: auto;
}

th,
td {
  padding: 0;
  text-align: left;
  vertical-align: top;
  border-left: 1px solid #fff;
}
<table>
  <thead>
    <tr>
      <th style="width:200px">Header 1</th>
      <th style="width:200px">Header 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="width:200px">Cell 1, Row 1</td>
      <td style="width:200px">Cell 2, Row 1</td>
    </tr>
    <tr>
      <td>Cell 1, Row 2</td>
      <td>Cell 2, Row 2</td>
    </tr>
    <tr>
      <td>Cell 1, Row 3</td>
      <td>Cell 2, Row 3</td>
    </tr>
    <tr>
      <td>Cell 1, Row 4</td>
      <td>Cell 2, Row 4</td>
    </tr>
    <tr>
      <td>Cell 1, Row 5</td>
      <td>Cell 2, Row 5</td>
    </tr>
    <tr>
      <td>Cell 1, Row 6</td>
      <td>Cell 2, Row 6</td>
    </tr>
    <tr>
      <td>Cell 1, Row 7</td>
      <td>Cell 2, Row 7</td>
    </tr>
    <tr>
      <td>Cell 1, Row 8</td>
      <td>Cell 2, Row 8</td>
    </tr>
    <tr>
      <td>Cell 1, Row 9</td>
      <td>Cell 2, Row 9</td>
    </tr>
    <tr>
      <td>Cell 1, Row 10</td>
      <td>Cell 2, Row 10</td>
    </tr>
    <tr>
      <td>Cell 1, Row 11</td>
      <td>Cell 2, Row 11</td>
    </tr>
    <tr>
      <td>Cell 1, Row 12</td>
      <td>Cell 2, Row 12</td>
    </tr>
  </tbody>
</table>

Проблема с этим решением заключается в том, что оно устанавливает фиксированную ширину как для таблицы, так и для ячеек в пикселях. Однако мне нужны <table style="width:100%"> и <td style="width:X%">. Как сделать фиксированную таблицу заголовков с таблицей и шириной ячейки в процентах в CSS, используя только одну html-таблицу и без JS?

Источник
jonhid
8 апреля 2018 в 07:39
0

Может быть, вы могли бы взглянуть на бутстрап w3schools.com/bootstrap/…

Pavel_K
8 апреля 2018 в 08:10
0

@Себастьян Шпейтель Спасибо. Я хотел отредактировать, но в редакторе все выглядело нормально.

Sebastian Speitel
8 апреля 2018 в 08:13
0

Просто нажмите аккуратно, прежде чем сохранить его. Редактор сделает за вас все форматирование

Ответы (7)

avatar
Tom
10 апреля 2018 в 10:11
4

Проверьте это решение, опубликованное по другому вопросу. Решение с фиксированным заголовком.

Или попробуйте эту скрипту

Содержимое заголовка помещается внутри "div" в "th". Этот div имеет абсолютную позицию и другие стили, чтобы отображать заголовок как фиксированный.

html, body{
  margin:0;
  padding:0;
  height:100%;
}
section {
  position: relative;
  border: 1px solid #000;
  padding-top: 37px;
  background: #500;
}
section.positioned {
  position: absolute;
  top:100px;
  left:100px;
  width:800px;
  box-shadow: 0 0 15px #333;
}
.container {
  overflow-y: auto;
  height: 200px;
}
table {
  border-spacing: 0;
  width:100%;
}
td + td {
  border-left:1px solid #eee;
}
td, th {
  border-bottom:1px solid #eee;
  background: #ddd;
  color: #000;
  padding: 10px 25px;
}
th {
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  color: transparent;
  border: none;
  white-space: nowrap;
}
th div{
  position: absolute;
  background: transparent;
  color: #fff;
  padding: 9px 25px;
  top: 0;
  margin-left: -25px;
  line-height: normal;
  border-left: 1px solid #800;
}
th:first-child div{
  border: none;
}
<section class="">
  <div class="container">
    <table>
      <thead>
        <tr class="header">
          <th>
            Table attribute name
            <div>Table attribute name</div>
          </th>
          <th>
            Value
            <div>Value</div>
          </th>
          <th>
            Description
            <div>Description</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>align</td>
          <td>left, center, right</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
        </tr>
        <tr>
          <td>bgcolor</td>
          <td>rgb(x,x,x), #xxxxxx, colorname</td>
          <td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
        </tr>
        <tr>
          <td>border</td>
          <td>1,""</td>
          <td>Specifies whether the table cells should have borders or not</td>
        </tr>
        <tr>
          <td>cellpadding</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
        </tr>
        <tr>
          <td>cellspacing</td>
          <td>pixels</td>
          <td>Not supported in HTML5. Specifies the space between cells</td>
        </tr>
        <tr>
          <td>frame</td>
          <td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
          <td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
        </tr>
        <tr>
          <td>rules</td>
          <td>none, groups, rows, cols, all</td>
          <td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
        </tr>
        <tr>
          <td>summary</td>
          <td>text</td>
          <td>Not supported in HTML5. Specifies a summary of the content of a table</td>
        </tr>
        <tr>
          <td>width</td>
          <td>pixels, %</td>
          <td>Not supported in HTML5. Specifies the width of a table</td>
        </tr>
      </tbody>
    </table>
  </div>
</section>
Pavel_K
10 апреля 2018 в 11:45
0

Не могли бы вы объяснить, что такое section.positioned?

Pavel_K
10 апреля 2018 в 12:06
0

А не могли бы вы объяснить, почему дублируется текст в th и div, я имею в виду этот <th>Table attribute name<div>Table attribute name</div></th>?

Tom
10 апреля 2018 в 12:08
0

@Pavel_K Раздел section.positioned не используется в скрипке. Это просто некоторый стиль для раздела. <th>Table attribute name<div>Table attribute name</div></th> Элемент div дает эффект фиксированного заголовка. Содержимое <th> повторяется в <div>, которому затем присваивается абсолютная позиция.

Munim Munna
11 апреля 2018 в 09:35
2

Если вы просто скопируете и вставите исходный код другого ответа в качестве ответа, это не нормально, вы можете просто поместить ссылку на этот ответ в комментарии. Но вы можете получить помощь из ответа с надлежащей ссылкой и сделать свой собственный ответ, который работает с фрагментом, предоставленным OP, который будет достоин нового ответа.

avatar
tao
15 апреля 2018 в 00:00
1

Преамбула: На общих принципах я считаю любой подход следующего типа:

  • разметка должна выглядеть как эта
  • этот язык или техника разрешены, а другой не

... ошибочен.

Интернет — это представление контента.
Какая бы технология ни использовалась за кулисами, она совершенно не имеет значения. Единственное, что имеет значение, — это результат: опыт конечного пользователя, доля рынка браузеров/устройств, поддерживающих решение, и, в конечном счете, успех продукта/кода (это вопрос усилий и результатов).

Это должен быть единственный аргумент.


Давайте посмотрим на это с практической точки зрения:

Вам нужна функциональность <table>, которая довольно удобна: она автоматически регулирует ширину всех ячеек в столбце в зависимости от содержимого. На лету. Конечно, это происходит за счет того, что таблицы невероятно медленны по сравнению с чем-либо еще. И именно поэтому их следует избегать и использовать только тогда, когда вам действительно нужна эта магия автоматической ширины и вам не нужна отзывчивость. Кстати: в настоящее время отсутствие адаптивного контента обходится вам дорого: Google обнаруживает это и решает, что ваш контент не подходит для сенсорных/узких устройств, и только по этой причине исключает вас из результатов поиска любых таких устройств (и , угадайте что - они составляют более 50% трафика!).

Но подождите: вы отбрасываете всю магию автоматической ширины и устанавливаете ширину ячейки на 50%. Это означает, что (технически) вообще не имеет смысла использовать здесь <table>. Вы можете легко получить этот макет (включая фиксированный заголовок), используя <div>, ваша страница будет намного быстрее, и у вас также будет больше возможностей для отклика. Единственным довольно незначительным преимуществом таблиц здесь является наличие border-collapse. Но это легко достижимо, используя отрицательное поле, равное ширине границы, для :not(:first-child) или :first-child для "ячеек".

.

В качестве аргумента, вот как я бы это сделал (в качестве домашнего задания):

.wrapper {
  max-height: 150px;
  overflow-y: auto; 
  display: inline-block;
  padding-top: 19px;
}
table {
  width: 100vw;
  border-collapse: collapse;
}
th, td {
  width: 50%;
}
thead tr{
  position:fixed;
  width: 100vw;
  overflow: hidden;
  color: #fff;
  background: #000;
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  top: 0;
  height: 18px;
  border-bottom: 1px solid #fff;
}

tbody {
  background: pink;
  overflow: auto;
}

th,
td {
  padding: 0;
  text-align: left;
  vertical-align: top;
  border-left: 1px solid #fff;
}

body {
  margin: 0;
  overflow-x: hidden
}
<div class="wrapper">
<table>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Cell 1, Row 1</td>
      <td>Cell 2, Row 1</td>
    </tr>
    <tr>
      <td>Cell 1, Row 2</td>
      <td>Cell 2, Row 2 Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet</td>
    </tr>
    <tr>
      <td>Cell 1, Row 3</td>
      <td>Cell 2, Row 3</td>
    </tr>
    <tr>
      <td>Cell 1, Row 4</td>
      <td>Cell 2, Row 4</td>
    </tr>
    <tr>
      <td>Cell 1, Row 5</td>
      <td>Cell 2, Row 5</td>
    </tr>
    <tr>
      <td>Cell 1, Row 6</td>
      <td>Cell 2, Row 6</td>
    </tr>
    <tr>
      <td>Cell 1, Row 7</td>
      <td>Cell 2, Row 7</td>
    </tr>
    <tr>
      <td>Cell 1, Row 8</td>
      <td>Cell 2, Row 8</td>
    </tr>
    <tr>
      <td>Cell 1, Row 9</td>
      <td>Cell 2, Row 8</td>
    </tr>
    <tr>
      <td>Cell 1, Row 10</td>
      <td>Cell 2, Row 10</td>
    </tr>
    <tr>
      <td>Cell 1, Row 11</td>
      <td>Cell 2, Row 11</td>
    </tr>
    <tr>
      <td>Cell 1, Row 12</td>
      <td>Cell 2, Row 12</td>
    </tr>
  </tbody>
</table>
</div>

Но на самом деле, учитывая, что вас не волнует автоматическая регулировка ширины ячеек на основе остальных столбцов, единственным решением, которое имеет смысл с технической точки зрения и с точки зрения производительности, является <div>s (независимо от того, что вы указали внутри него).

Что означает, что я постараюсь дать понять, что это стоит вам реальных денег (ваша страница работает вяло на x % целевых устройств, что отталкивает ваших клиентов на другой веб-сайт, который, вероятно, использует что-то технически надежное. Это <table>? Большинство, если не все ваши клиенты, скажут, что это стол. Гладкий, для разнообразия.

.table {
  width: 100vw;
  padding-top: 19px;
  position: relative;
}
.thead >div >span, .tbody>div > span {
  width: 50%;
}
.thead:after {
  position: absolute;
  background: black;
  content: '';
  width: 17px;
  height: 18px;
  right: 0;
  top: 0;
}
.thead > div{
  position:fixed;
  width: 100vw;
  max-width: 100%;
  color: #fff;
  background: #000;
  display: flex;
  top: 0;
  height: 18px;
  border-bottom: 1px solid rgba(255,255,255,.65);
  overflow-y: scroll;
  overflow-x: hidden;
}

.tbody{
  background: pink;
  display: flex;
  flex-direction: column;
  overflow-y: scroll;
  max-height: 150px;
}
.tbody > div {
  display: flex;
  flex: 1 0 auto;
  border-bottom: 1px solid rgba(255,255,255,.21);
}
.tbody > div> span, .thead>div>span {
  flex: 0 0 50%;
  padding: 0;
  text-align: left;
}
.thead > div > span:not(:first-child) ,
.tbody > div > span:not(:first-child) {
  margin-left: -1px;
  border-left: 1px solid rgba(255,255,255,.21);
}

body {
  margin: 0;
  overflow-x: hidden
}
<div class="table">
  <div class="thead">
    <div>
      <span>Header 1</span>
      <span>Header 2</span>
    </div>
  </div>
  <div class="tbody">
    <div>
      <span>Cell 1, Row 1</span>
      <span>Cell 2, Row 1</span>
    </div>
    <div>
      <span>Cell 1, Row 2</span>
      <span>Cell 2, Row 2 Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet</span>
    </div>
    <div>
      <span>Cell 1, Row 3</span>
      <span>Cell 2, Row 3</span>
    </div>
    <div>
      <span>Cell 1, Row 4</span>
      <span>Cell 2, Row 4</span>
    </div>
    <div>
      <span>Cell 1, Row 5</span>
      <span>Cell 2, Row 5</span>
    </div>
    <div>
      <span>Cell 1, Row 6</span>
      <span>Cell 2, Row 6</span>
    </div>
    <div>
      <span>Cell 1, Row 7</span>
      <span>Cell 2, Row 7</span>
    </div>
    <div>
      <span>Cell 1, Row 8</span>
      <span>Cell 2, Row 8</span>
    </div>
    <div>
      <span>Cell 1, Row 9</span>
      <span>Cell 2, Row 8</span>
    </div>
    <div>
      <span>Cell 1, Row 10</span>
      <span>Cell 2, Row 10</span>
    </div>
    <div>
      <span>Cell 1, Row 11</span>
      <span>Cell 2, Row 11</span>
    </div>
    <div>
      <span>Cell 1, Row 12</span>
      <span>Cell 2, Row 12</span>
    </div>
  </div>
</div>

Большинство людей, думая о табличных данных, автоматически представляют себе Excel. Вы думаете, что из всех продуктов MS Excel в Интернете — единственное место, где <table> имеют смысл, верно? Оказывается, они слишком медленные, и использование абсолютно позиционированных <div> обеспечивает лучший пользовательский опыт.

Но, может быть, MS не лучший пример, в конце концов, они проиграли войны браузеров, верно? Давайте посмотрим на Google Таблицы. Вы уже догадались: это Google <div>s.

Pavel_K
15 апреля 2018 в 07:51
0

Извините, я не понял. Я спрашиваю о решении с шириной таблицы и ячеек в %. Ваше решение находится в px. Пожалуйста, объясни.

tao
15 апреля 2018 в 07:54
0

Вы имеете в виду это? Ширина стола значения не имеет. Он вполне может быть размером со своего родителя. Столбцы представляют собой проценты. Это то, что вы просили, верно?

Pavel_K
15 апреля 2018 в 07:59
0

О, я не заметил, что вы используете div вместо table. Но как выровнять левую границу Header 2 с границами tbody? Я имею в виду, что есть некоторое смещение из-за прокрутки.

tao
15 апреля 2018 в 08:00
0

Возможно, вам стоит прочитать ее. Когда будет время :)

Pavel_K
15 апреля 2018 в 08:02
0

Я отредактировал свой комментарий.

tao
15 апреля 2018 в 08:07
0

Правильное техническое решение (сохранение наиболее ценного актива макета таблицы — возможность настраивать ширину столбцов в соответствии с содержимым), которое также работает в разных браузерах / на разных устройствах, в отличие от всего, что вы можете достичь с помощью одного лишь CSS, подразумевает использование div в качестве заголовка. и обновление их ширины при изменении таблицы или размера окна. Здесь я просто добавил полосу прокрутки к заголовку и таблице, чтобы они были одинаковой ширины. Любое профессиональное решение (платный плагин) для фиксированных макетов таблиц использует JavaScript. Как вы думаете, почему?

Pavel_K
15 апреля 2018 в 08:08
0

Ok. Спасибо за ваше решение. Это интересно.

avatar
romuleald
13 апреля 2018 в 22:31
0

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

Если вам не нужен Internet Explorer, вы можете использовать position: sticky. https://developer.mozilla.org/en-US/docs/Web/CSS/position JS не требуется.

.wrapwrap {
    position: relative;
}

.wrapper {
    height: 100px;
    overflow: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
}

thead {
  position: absolute;
  top: 0;
  width: 100%;
  display: inherit;

}

tbody {
  background: pink;
}

th {
    background: #000;
    color: #FFF;
}

th,
td {
  padding: 0;
  text-align: left;
  vertical-align: top;
  border-left: 1px solid #fff;
}
<h1>Position Sticky</h1>
<div class="wrapwrap">><div class="wrapper"><table>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Cell 1, Row 1</td>
      <td>Cell 2, Row 1</td>
    </tr>
    <tr>
      <td>Cell 1, Row 2</td>
      <td>Cell 2, Row 2</td>
    </tr>
    <tr>
      <td>Cell 1, Row 3</td>
      <td>Cell 2, Row 3</td>
    </tr>
    <tr>
      <td>Cell 1, Row 4</td>
      <td>Cell 2, Row 4</td>
    </tr>
    <tr>
      <td>Cell 1, Row 5</td>
      <td>Cell 2, Row 5</td>
    </tr>
    <tr>
      <td>Cell 1, Row 6</td>
      <td>Cell 2, Row 6</td>
    </tr>
    <tr>
      <td>Cell 1, Row 7</td>
      <td>Cell 2, Row 7</td>
    </tr>
    <tr>
      <td>Cell 1, Row 8</td>
      <td>Cell 2, Row 8</td>
    </tr>
    <tr>
      <td>Cell 1, Row 9</td>
      <td>Cell 2, Row 9</td>
    </tr>
    <tr>
      <td>Cell 1, Row 10</td>
      <td>Cell 2, Row 10</td>
    </tr>
    <tr>
      <td>Cell 1, Row 11</td>
      <td>Cell 2, Row 11</td>
    </tr>
    <tr>
      <td>Cell 1, Row 12</td>
      <td>Cell 2, Row 12</td>
    </tr>
  </tbody>
</table></div></div>
Pavel_K
14 апреля 2018 в 05:42
0

Спасибо за ваше решение, но в вашем решении шапка не исправлена.

romuleald
14 апреля 2018 в 10:16
0

Они есть, какой у вас браузер?

Pavel_K
14 апреля 2018 в 10:23
0

Я использую FF 58 64 бита

romuleald
14 апреля 2018 в 13:53
0

мда, грустно, FF не поддерживает липкое внутреннее переполнение: авто; github.com/w3c/csswg-drafts/issues/865

romuleald
14 апреля 2018 в 14:08
0

Тем не менее, я думаю, моя последняя попытка может быть решением

avatar
Brainfeeder
13 апреля 2018 в 14:53
1

Я знаю, что OP попросил решение без js... но, возможно, это могло бы вам помочь. Я написал функцию jQuery, так как у меня было много заголовков таблиц... Проверьте jsFiddle: https://jsfiddle.net/qa4q12Lw/18/

jQuery.fn.stickTableHeaders = function() {
  return this.each(function()
  {
    if(!$(this).is('[data-stick-headers="false"]') && !$(this).is('.table-sticked')) {
      var table = $(this),
            header = table.children('thead'),
            sticked = $('<table></table>').addClass('table table-sticked').css({'margin':'0'}).append(header.clone());

                // Manualy aply styles to the cloned thead and everything in it. Don't know if you'll need this?
      sticked.find('th').css({'backgroundColor': '#fff'}).removeAttr('width');

    $(window).resize(function() {
      // Be sure it recalculates stuff on window resize
      sticked.find('th').each(function() {
          var headerTH = header.find('th').eq($(this).index());
          if(headerTH.is('[width]') || headerTH.is(':first-child') || headerTH.is(':last-child')) {
            $(this).width(header.find('th').eq($(this).index()).width());
          }
          else {
            $(this).width(header.find('th').eq($(this).index()).width());
          }
        });

        table.css({'marginTop':-header.height()});

    }).trigger('resize');
                // top property should be position where to stay sticky
      sticked.css({'display':'table','width':'100%','position':'sticky','top':0, 'zIndex':'10'});

      $(this).before(sticked);
    }
  });
};

Чтобы получить наилучший результат, вы должны установить width на большинство th.

avatar
vals
12 апреля 2018 в 20:56
1

Вы можете получить это, используя стиль display: flex для строк таблицы. А затем установить ширину первого элемента с помощью flex-basis (в процентах, как вы просили)

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

Таким образом, установка ширины на 50% в заголовке дает другой результат, чем то же самое в теле.

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

Чтобы решить эту проблему, я добавил полосу прокрутки к голове.

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

table {
  width: 450px;
  border-collapse: collapse;
}

thead {
  display: block;
  width: 450px;
  overflow: auto;
  color: #fff;
  background: #000;
}

tbody {
  display: block;
  width: 450px;
  height: 200px;
  background: pink;
  overflow: auto;
}

tr {
  display: flex;
}
thead tr {
  overflow-y: scroll;
}

th,
td {
  padding: 0;
  text-align: left;
  vertical-align: top;
  border-left: 1px solid #fff;
}

th:first-child,
td:first-child {
   flex-basis: 50%;
}
<table>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Cell 1, Row 1</td>
      <td>Cell 2, Row 1</td>
    </tr>
    <tr>
      <td>Cell 1, Row 2</td>
      <td>Cell 2, Row 2</td>
    </tr>
    <tr>
      <td>Cell 1, Row 3</td>
      <td>Cell 2, Row 3</td>
    </tr>
    <tr>
      <td>Cell 1, Row 4</td>
      <td>Cell 2, Row 4</td>
    </tr>
    <tr>
      <td>Cell 1, Row 5</td>
      <td>Cell 2, Row 5</td>
    </tr>
    <tr>
      <td>Cell 1, Row 6</td>
      <td>Cell 2, Row 6</td>
    </tr>
    <tr>
      <td>Cell 1, Row 7</td>
      <td>Cell 2, Row 7</td>
    </tr>
    <tr>
      <td>Cell 1, Row 8</td>
      <td>Cell 2, Row 8</td>
    </tr>
    <tr>
      <td>Cell 1, Row 9</td>
      <td>Cell 2, Row 9</td>
    </tr>
    <tr>
      <td>Cell 1, Row 10</td>
      <td>Cell 2, Row 10</td>
    </tr>
    <tr>
      <td>Cell 1, Row 11</td>
      <td>Cell 2, Row 11</td>
    </tr>
    <tr>
      <td>Cell 1, Row 12</td>
      <td>Cell 2, Row 12</td>
    </tr>
  </tbody>
</table>
avatar
scooterlord
11 апреля 2018 в 07:06
3

Ну, вот мое решение.

Для HTML вам просто нужно обернуть две оболочки div, а в thead th вам нужно дублировать код - я кратко объясню почему.

Вам нужна оболочка .table-outer для создания необходимых padding-top и position:relative, которые будут вмещать заголовок таблицы fixed.

Оболочка .table-wrap используется для прокрутки содержимого таблицы. Одну оболочку нельзя использовать для абсолютного позиционирования заголовка, поскольку она будет прокручиваться вместе с родителем.

Теперь я продублировал и обернул содержимое th внутри p и span. Элемент span используется для правильного оформления и позиционирования заголовка. Поначалу p может показаться ненужным, но вот что он делает: он обеспечивает правильное расширение th в тех случаях, когда содержимое th имеет большую ширину, чем самое большое содержимое td.

HTML

<div class="table-outer">
  <div class="table-wrap">
    <table>
      <thead>
        <tr>
          <th>
            <p>Header 1</p><span>Header 1</span></th>
          <th>
            <p>Header 1</p><span>Header 2</span></th>
        </tr>
      </thead>
      <tbody>
       ...
      </tbody>
    </table>
  </div>
</div>

CSS

.table-outer {
  padding-top: 20px;
  position: relative;
  height: 100px;
  overflow: hidden;
}

.table-wrap {
  overflow-x: auto;
  overflow-y: scroll;
  width: 100%;
  height: 100%;
}
thead th p {
  overflow: hidden;
  height: 0;
  margin: 0;
  padding: 0;
}

thead th span {
  position: absolute;
  top: 0;
  display: block;
  background: #000;
  color: #fff;
  width: 100%;
}

Вот рабочая скрипта вместе с небольшим обновлением, которое показывает другой контент в таблице: https://jsfiddle.net/8fa1w922/ https://jsfiddle.net/8fa1w922/2/

avatar
Sebastian Speitel
8 апреля 2018 в 08:11
2

Элементы с некоторым типом display:table не могут иметь полосы прокрутки, но вы можете создать другую таблицу внутри <div>, которая может выполнять часть переполнения.

table {
  width: 300px;
  border-collapse: collapse;
}

#scroll {
  overflow-y: auto;
  height: 200px;
  width: fit-content;
}

thead {
  color: #fff;
  background: #000;
}

tbody {
  background: pink;
}

th,
td {
  padding: 0;
  text-align: left;
  vertical-align: top;
  border-left: 1px solid #fff;
}
<table>
  <thead>
    <tr>
      <th style="width:40%">Header 1</th>
      <th style="width:60%">Header 2</th>
    </tr>
  </thead>
</table>
<div id="scroll">
  <table>
    <tbody>
      <tr>
        <td style="width:40%">Cell 1, Row 1</td>
        <td style="width:60%">Cell 2, Row 1</td>
      </tr>
      <tr>
        <td>Cell 1, Row 2</td>
        <td>Cell 2, Row 2</td>
      </tr>
      <tr>
        <td>Cell 1, Row 3</td>
        <td>Cell 2, Row 3</td>
      </tr>
      <tr>
        <td>Cell 1, Row 4</td>
        <td>Cell 2, Row 4</td>
      </tr>
      <tr>
        <td>Cell 1, Row 5</td>
        <td>Cell 2, Row 5</td>
      </tr>
      <tr>
        <td>Cell 1, Row 6</td>
        <td>Cell 2, Row 6</td>
      </tr>
      <tr>
        <td>Cell 1, Row 7</td>
        <td>Cell 2, Row 7</td>
      </tr>
      <tr>
        <td>Cell 1, Row 8</td>
        <td>Cell 2, Row 8</td>
      </tr>
      <tr>
        <td>Cell 1, Row 9</td>
        <td>Cell 2, Row 9</td>
      </tr>
      <tr>
        <td>Cell 1, Row 10</td>
        <td>Cell 2, Row 10</td>
      </tr>
      <tr>
        <td>Cell 1, Row 11</td>
        <td>Cell 2, Row 11</td>
      </tr>
      <tr>
        <td>Cell 1, Row 12</td>
        <td>Cell 2, Row 12</td>
      </tr>
      <tr>
        <td>Cell 1, Row 12</td>
        <td>Cell 2, Row 12</td>
      </tr>
      <tr>
        <td>Cell 1, Row 12</td>
        <td>Cell 2, Row 12</td>
      </tr>
      <tr>
        <td>Cell 1, Row 12</td>
        <td>Cell 2, Row 12</td>
      </tr>
    </tbody>
  </table>
Pavel_K
8 апреля 2018 в 08:13
0

Спасибо за ваш ответ. Но в вашем решении заголовок таблицы не исправлен.

Sebastian Speitel
8 апреля 2018 в 08:14
0

Итак, ваши столбцы <tbody> не должны совпадать с заголовком?

Pavel_K
8 апреля 2018 в 08:15
0

Извините, не понял. Запустите фрагмент кода в вопросе, вы увидите, что мне нужно.

Sebastian Speitel
8 апреля 2018 в 08:16
0

Является ли фрагмент кода в вопросе ожидаемым результатом?

Pavel_K
8 апреля 2018 в 08:18
0

Да, ожидаемый результат. Единственная проблема в том, что ширина px, а мне нужна %.

Sebastian Speitel
8 апреля 2018 в 08:19
0

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

Pavel_K
8 апреля 2018 в 08:22
0

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

Sebastian Speitel
8 апреля 2018 в 08:28
0

О, извините, теперь я понимаю, что вы имеете в виду под фиксированным и, следовательно, что вы хотите

Sebastian Speitel
8 апреля 2018 в 08:37
0

Это решит вашу проблему?

Pavel_K
8 апреля 2018 в 08:41
0

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