Как отобразить полосу прокрутки в таблице html

86

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

Я хочу, чтобы он выглядел как метод 2 в этом URL: http://www.cssplay.co.uk/menu/tablescroll.html

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

tbody {
  height: 80em;
  overflow: scroll;
}
<table border=1 id="qandatbl" align="center">
  <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
  </tr>

  <tbody>
    <tr>
      <td class='qid'></td>
      <td class="options"></td>
      <td class="duration"></td>
    </tr>
  </tbody>
</table>

БрюсиБандит
источник
Почему бы вам не использовать код из примера метода? К <tbody>сожалению, использовать нельзя .
Майк Парк

Ответы:

164

Что-то вроде этого?

http://jsfiddle.net/TweNm/

Идея состоит в том, чтобы обернуть <table>объект нестатически позиционированным, <div>который имеет overflow:autoсвойство CSS. Затем разместите элементы в <thead>абсолютно.

#table-wrapper {
  position:relative;
}
#table-scroll {
  height:150px;
  overflow:auto;  
  margin-top:20px;
}
#table-wrapper table {
  width:100%;

}
#table-wrapper table * {
  background:yellow;
  color:black;
}
#table-wrapper table thead th .text {
  position:absolute;   
  top:-20px;
  z-index:2;
  height:20px;
  width:35%;
  border:1px solid red;
}
<div id="table-wrapper">
  <div id="table-scroll">
    <table>
        <thead>
            <tr>
                <th><span class="text">A</span></th>
                <th><span class="text">B</span></th>
                <th><span class="text">C</span></th>
            </tr>
        </thead>
        <tbody>
          <tr> <td>1, 0</td> <td>2, 0</td> <td>3, 0</td> </tr>
          <tr> <td>1, 1</td> <td>2, 1</td> <td>3, 1</td> </tr>
          <tr> <td>1, 2</td> <td>2, 2</td> <td>3, 2</td> </tr>
          <tr> <td>1, 3</td> <td>2, 3</td> <td>3, 3</td> </tr>
          <tr> <td>1, 4</td> <td>2, 4</td> <td>3, 4</td> </tr>
          <tr> <td>1, 5</td> <td>2, 5</td> <td>3, 5</td> </tr>
          <tr> <td>1, 6</td> <td>2, 6</td> <td>3, 6</td> </tr>
          <tr> <td>1, 7</td> <td>2, 7</td> <td>3, 7</td> </tr>
          <tr> <td>1, 8</td> <td>2, 8</td> <td>3, 8</td> </tr>
          <tr> <td>1, 9</td> <td>2, 9</td> <td>3, 9</td> </tr>
          <tr> <td>1, 10</td> <td>2, 10</td> <td>3, 10</td> </tr>
          <!-- etc... -->
          <tr> <td>1, 99</td> <td>2, 99</td> <td>3, 99</td> </tr>
        </tbody>
    </table>
  </div>
</div>

Ричард Дж. П. Ле Гуен
источник
15
Как насчет отсутствия столбцов с фиксированной шириной?
Fractaliste
3
Я попробовал ваш ответ, но столбцы заголовка не выровнены. Я использовал только ваш css в теге стиля внутри тега body, куда я скопировал вашу таблицу
Антонио
Отличное решение, но у меня с ним проблемы. При попытке скрыть строку и установить display: none между строками есть пробелы. С обычным столом дело обстоит иначе. Есть идеи, советы или предложения?
Даниил Шевелев
@Antonio: У меня была та же проблема (центрированные * столбцы заголовка кажутся невыровненными), но добавление transform: translateX(-50%)помогло мне [* центрированный - это стандартный стиль в Firefox, который удаляется опцией «нормализовать CSS» в JSFiddle этого ответа]
Сора.
46

Вы должны вставить свой <table>в, <div>чтобы он имел фиксированный размер и <div>стиль, который вы должны установить overflow: scroll.

Hossein Barzegari
источник
1
дал высоту 500 пикселей для моего div, и он работал нормально. <div style = "overflow: scroll; height: 500px;">
Зигглер,
3
Не знаю, почему все так усложнили. Это должен быть принятый ответ.
amallard
1
Это, безусловно, самое простое решение. Могут быть предостережения при добавлении div с переполнением и фиксированной высотой, но это решение, по крайней мере, настроит вас в правильном направлении.
lsimonetti
1
Отличный ответ, дружище! Приветствую вас
:)
1
Это должен быть принятый ответ. Просто, прямо по делу, и я больше ничего этим не разрушаю.
Я очень стараюсь, но плачу сильнее
40

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

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

Вот пример, в котором есть все необходимые функции для репликации таблицы, на которую ссылается OP: jsFiddle

Чтобы сделать его идентичным эталону, необходимо изменить цвета и границы. Информация о том, как вносить такие изменения, представлена ​​в комментариях CSS.

Вот код:

/*the following html and body rule sets are required only if using a % width or height*/
/*html {
width: 100%;
height: 100%;
}*/
body {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
  text-align: center;
  background: white;
}
.scrollingtable {
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /*if you want a fixed width, set it here, else set to auto*/
  min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/
  height: 188px/*100%*/; /*set table height here; can be fixed value or %*/
  min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 15px;
  line-height: 20px;
  padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
  text-align: left;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /*this determines column header height*/
}
.scrollingtable > div:before {
  top: 0;
  background: cornflowerblue; /*header row background color*/
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;
}
.scrollingtable > div > div {
  min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/
  max-height: 100%;
  overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/
  overflow-x: hidden;
  border: 1px solid black; /*border around table body*/
}
.scrollingtable > div > div:after {background: white;} /*match page background color*/
.scrollingtable > div > div > table {
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /*inverse of column header height*/
  /*margin-right: 17px;*/ /*uncomment if using % width*/
}
.scrollingtable > div > div > table > caption {
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
  content: "";
  display: block;
  min-height: 20px; /*match column header height*/
  padding-top: 1px;
  border-left: 1px solid black; /*borders between header cells*/
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
  position: absolute;
  width: 100px;
  top: -1px; /*inverse border-width*/
  background: white; /*match page background color*/
}
.scrollingtable > div > div > table > tbody > tr:after {
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /*inverse of border width*/
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /*match column header height*/
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /*borders between body cells*/
<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"></div></th>
            <th><div label="Column 2"></div></th>
            <th><div label="Column 3"></div></th>
            <th>
              <!--more versatile way of doing column label; requires 2 identical copies of label-->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->

ДокторDestructo
источник
хорошая работа. Однако у меня есть таблица с 15 столбцами, и теперь я не могу разместить таблицу на странице без горизонтальной полосы прокрутки. Я пробовал настроить ваш css, ваш красиво закодированный css, чтобы разместить больше столбцов с динамической шириной, но ничего, что я меняю, кроме ширины таблицы, не имеет значения. Если я изменю ширину таблицы на 100%, то таблица будет отображаться по ширине таблицы, но поскольку ширина столбцов не будет переноситься, я все равно не могу видеть все 15 столбцов данных. У меня почти есть таблица с прокруткой, которая выглядит ужасно, поэтому любая помощь приветствуется.
nanker
ой, погоди, нет горизонтальной полосы прокрутки, таблица просто отрезается.
nanker
@nanker Если вам нужна горизонтальная прокрутка и вы хотите использовать крошечный кусочек JavaScript, вам следует проверить этот ответ . Это лучший способ сделать таблицу с прокруткой, о которой я знаю. Когда я опубликовал этот ответ, не было хорошего способа выполнить горизонтальную прокрутку только с помощью CSS, но я не изучал его некоторое время, поэтому я не знаю, что возможно сейчас.
DoctorDestructo
Отличная работа. Не могли бы вы прокомментировать, как настроить несколько строк заголовков? Простое повторение <tr><th></th>..</tr>конструкции явно не работает. Благодарю.
Дэвид И. Макинтош
@ DavidI.McIntosh Многострочный заголовок может оказаться сложной задачей при использовании этой техники. Добавить строки было бы легко, но я не уверен, как получить горизонтальные границы между ними. Возможно, вы захотите попробовать решение JavaScript, которое я указал в своем предыдущем комментарии, если вы не можете использовать JS по какой-либо причине.
DoctorDestructo
3

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

Одна таблица - это строка заголовка.

Секунды также являются <table>тегами, но <div>имеют статическую высоту и прокрутку переполнения.

Цви
источник
1

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

Если вы этого хотите, замените height: x;на max-height: x;и overflow:scrollна overflow:auto.

Кроме того, вы можете использовать overflow-xи, overflow-yесли хотите, и, очевидно, то же самое работает по горизонтали сwidth : x;

Бен
источник
0

Если вы дойдете до того, что все упомянутые решения не работают (как у меня), сделайте следующее:

  • Создайте две таблицы. Один для заголовка, а другой для тела
  • Дайте двум таблицам разные родительские контейнеры / div
  • Создайте стиль для div второй таблицы, чтобы разрешить вертикальную прокрутку его содержимого.

Вот так, в твоем HTML

<div class="table-header-class">
    <table>
       <thead>
          <tr>
            <th>Ava</th>
            <th>Alexis</th>
            <th>Mcclure</th>
          </tr>
       </thead>
    </table>
</div>
<div class="table-content-class">
   <table>
       <tbody>
          <tr>
            <td>I am the boss</td>
            <td>No, da-da is not the boss!</td>
            <td>Alexis, I am the boss, right?</td>
          </tr>
       </tbody>
    </table>
</div>

Затем задайте стиль родительской второй таблицы, чтобы разрешить вертикальную прокрутку в вашем CSS

    .table-content-class {
        overflow-y: scroll;    // use auto; or scroll; to allow vertical scrolling; 
        overflow-x: hidden;    // disable horizontal scroll 
    }
Кака Руто
источник
Это та же реализация, что и ответ Цви годом ранее.
TylerH
0

просто добавь на стол

style="overflow-x:auto;"

<table border=1 id="qandatbl" align="center" style="overflow-x:auto;">
    <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
    </tr>

   <tbody>
    <tr>
    <td class='qid'></td>
    <td class="options"></td>
    <td class="duration"></td>
    </tr>
    </tbody>
</table>

style = "overflow-x: auto;" `

Мастер места обучения
источник
Вопрос заключался в том, как заставить тело таблицы прокручиваться по вертикали, а заголовок столбца остается на месте.
giraffedata
0

Очень легко, просто обернуть таблицу в DIV , который имеет overflow-y:scroll;и overflow-x:scrollсвойства, и сделать DIV имеет ширину и длину , меньшую , чем за столом. ЭТО СРАБОТАЕТ!!!

Гость
источник
Хорошо, добавлю в следующем ответе.
Гость
Хорошо, сделал это, я еще не знаю, как правильно делать отступы в коде при переполнении стека.
Гость
0

CSS: div{ overflow-y:scroll; overflow-x:scroll; width:20px; height:30px; } table{ width:50px; height:50px; }

Вы можете сделать таблицу и DIV вокруг нее любого размера, который вам нужен, просто убедитесь, что DIV меньше таблицы. Вы ДОЛЖНЫ содержать таблицу внутри DIV.

Гость
источник