Как иметь горизонтальную полосу прокрутки в таблице и вертикальную полосу прокрутки на основной странице, а также использовать фиксированную позицию для заголовка таблицы html?

В названии действительно сложно объяснить, что мне нужно, поэтому вот пример.

Это моя таблица:

body { 
  margin: 0;
  padding: 0; 
}

header { 
  margin-bottom: 15px;
  display: flex;
  justify-content: center;
}

.header__info-wrapper { 
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 10px;
}

.infoboard__wrapper { 
  display: flex;
  gap: 15px;
  background-color: #f1f1f1;
  padding: 5px 10px;
  border-radius: 10px;
}

.title { 
  font-size: 30px;
  font-weight: bold;
}

.view {
  margin: auto;
  width: 100vw;
}

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

  table-layout: fixed;
}

th {
  position: sticky;
  top:0;  
}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
  background-color: white;
  box-sizing: border-box;    
}

table th:not(:nth-child(1)):not(:nth-child(2)) {
  width: 300px;
}

tr:nth-child(even) td {
  background-color: #dddddd;
}

.wrapper {
  position: relative;
  /* overflow-x: auto; */
  height: 100vh;
}

.sticky-col {  
  position: sticky;
  z-index: 1;
}

th.sticky-col{
  z-index: 2;
}

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

.second-col {
  width: 150px;
  min-width: 150px;
  max-width: 150px;
  left: 100px;
}

.wrapped-content{
  width: 250px;
  white-space: normal;
}
<header>
    <div class = "header__info-wrapper">
      <div class = "title">Some Title</div>
      <div class = "infoboard__wrapper">
        <div class = "basic__info">
          <div>Total Number:</div>
          <div>
            <ifx-number-indicator id = "number__indicator-total"></ifx-number-indicator>
          </div>
        </div>
        <div class = "basic__info">
          <div>Completed:</div>
          <div>
            <ifx-number-indicator id = "number__indicator-completed"></ifx-number-indicator>
          </div>
        </div>
        <div class = "basic__info">
          <div>Planned:</div>
          <div>
            <ifx-number-indicator id = "number__indicator-planned"></ifx-number-indicator>
          </div>
        </div>
      </div>
    </div>
  </header>

  <div class = "view">
    <div class = "wrapper">
      <table class = "table">
        <thead>
          <tr>
            <th class = "sticky-col first-col">Preview</th>
            <th class = "sticky-col second-col">Component</th>
            <th>Version 1</th>
            <th>Version 2</th>
            <th>Version 3</th>
            <th>Version 4</th>
            <th>Version 5</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><div class = "wrapped-content">Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog Goog Goog</div></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>
          <tr>
            <td class = "sticky-col first-col">4</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">5</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">6</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</td>
            <td class = "sticky-col second-col">Larry</td>
            <td>Wen</td>
            <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
          </tr>
          <tr>
            <td class = "sticky-col first-col">7</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>

Это то поведение, которое я хочу! Исправлено th и исправлены первые два столбца + фиксированная горизонтальная полоса прокрутки. Проблема в том, что, поскольку на теле появляется горизонтальная полоса прокрутки, все тело движется! Таким образом, содержимое внутри заголовка тоже перемещается. Я не хочу этого. Я хочу, чтобы горизонтальная полоса прокрутки перемещала только содержимое внутри таблицы, а не все тело. Я хочу, чтобы вертикальная полоса прокрутки находилась на теле, чтобы можно было прокручивать всю страницу вниз.

Если вы раскомментируете overflow-x: auto;, то горизонтальная полоса прокрутки переместит содержимое таблицы, но вертикальная полоса прокрутки переместит только содержимое таблицы, а не все тело, чего я и хочу! Кроме того, из-за содержимого заголовка на самом деле имеется две полосы прокрутки.

Как добиться того, чего я хочу? Как сделать так, чтобы горизонтальная полоса прокрутки перемещала только содержимое таблицы, а вертикальная — всю страницу?

Обновлять:

Скриншоты границы td перед движением прокрутки.

Скриншоты границы td после перемещения прокрутки.

Скриншоты границы перед движением прокрутки.

Скриншоты границы после прокрутки.

Границы не совпадают:

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Шаги, которые необходимо сделать, следующие:

  • Добавьте overflow-x: hidden; к элементу body.
  • Добавьте width: 100% и overflow: scroll к элементу wrapper элемента table.
  • Рассчитайте высоту заголовка с помощью JavaScript и установите высоту как настраиваемое свойство CSS.
  • Наконец, добавьте height: calc(100vh - var(--header-height) - 15px); к элементу wrapper. (15 пикселей — высота полосы прокрутки)

Обновлено: Вторая проблема, с которой вы сталкиваетесь, — это граница, которая становится невидимой при прокрутке по горизонтали или вертикали. Я попробовал несколько решений и нашел ответ. Причиной этой проблемы является border-collapse: collapse на элементе table. Удаление его и изменение border-spacing на 0 делает свою работу, и граница теперь остается при прокрутке, но с этим возникла проблема. Граница td и th перекрывает родственную границу и в некоторых областях создает толстую (2 пикселя) границу. Я решил эту проблему, удалив границу из td и th и заменив ее box-shadow расширением 1px с размытием 0. Еще одно небольшое изменение: отсутствовала верхняя граница таблицы, поэтому я добавил border-top: 1px; к элементам th в thead. Теперь он выглядит идеально.

Кроме того, я изменил позицию left элемента .second-col «Компонент» на 150px. Теперь это предотвращает его горизонтальное перемещение в соответствии с вашим запросом на комментарий.

Вы можете просмотреть обновленный результат во фрагменте ниже.

const headerEl = document.querySelector("header");
const headerHeight = headerEl.offsetHeight;
const wrapperEl = document.querySelector(".wrapper");

wrapperEl.style.setProperty('--header-height', `${headerHeight}px`);
body {
    margin: 0;
    padding: 0;
    overflow-x: hidden;
}

header {
    margin-bottom: 15px;
    display: flex;
    justify-content: center;
}

.header__info-wrapper {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 10px;
}

.infoboard__wrapper {
    display: flex;
    gap: 15px;
    background-color: #f1f1f1;
    padding: 5px 10px;
    border-radius: 10px;
}

.title {
    font-size: 30px;
    font-weight: bold;
}

.view {
    margin: auto;
    width: 100vw;
}

table {
    width: 100%;
    table-layout: fixed;

    /* Removed the border-collapse and added border spacing 0  */
    border-spacing: 0;
}

thead tr th {
    /* Added the border top to the table header */
    border-top: 1px solid #dddddd;
}

th {
    position: sticky;
    top: 0;
}

td,
th {
    text-align: left;
    padding: 8px;
    
    /* Removed the border */
    border: none;

    /* Added the box-shadow as the border */
    box-shadow: 0 0 0 1px #dddddd;
    
    background-color: white;
    box-sizing: border-box;
}

table th:not(:nth-child(1)):not(:nth-child(2)) {
    width: 300px;
}

tr:nth-child(even) td {
    background-color: #dddddd;
}

.wrapper {
    position: relative;
    width: 100%;
    height: calc(100vh - var(--header-height) - 15px);
    overflow: scroll;
}

.sticky-col {
    position: sticky;
    z-index: 1;
}

th.sticky-col {
    z-index: 2;
}

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

.second-col {
    width: 150px;
    min-width: 150px;
    max-width: 150px;
    left: 150px;
}

.wrapped-content {
    width: 250px;
    white-space: normal;
}
<header>
    <div class = "header__info-wrapper">
        <div class = "title">Some Title</div>
        <div class = "infoboard__wrapper">
            <div class = "basic__info">
                <div>Total Number:</div>
                <div>
                    <ifx-number-indicator id = "number__indicator-total"></ifx-number-indicator>
                </div>
            </div>
            <div class = "basic__info">
                <div>Completed:</div>
                <div>
                    <ifx-number-indicator id = "number__indicator-completed"></ifx-number-indicator>
                </div>
            </div>
            <div class = "basic__info">
                <div>Planned:</div>
                <div>
                    <ifx-number-indicator id = "number__indicator-planned"></ifx-number-indicator>
                </div>
            </div>
        </div>
    </div>
</header>

<div class = "view">
    <div class = "wrapper">
        <table class = "table">
            <thead>
                <tr>
                    <th class = "sticky-col first-col">Preview</th>
                    <th class = "sticky-col second-col">Component</th>
                    <th>Version 1</th>
                    <th>Version 2</th>
                    <th>Version 3</th>
                    <th>Version 4</th>
                    <th>Version 5</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>
                    <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>
                        <div class = "wrapped-content">Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog Goog Goog
                        </div>
                    </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>
                <tr>
                    <td class = "sticky-col first-col">4</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">5</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">6</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</td>
                    <td class = "sticky-col second-col">Larry</td>
                    <td>Wen</td>
                    <td>Goog Goog Goog GoogGoog Goog Goog Goog Goog Goog</td>
                </tr>
                <tr>
                    <td class = "sticky-col first-col">7</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>

Примечание. Возможно, вы заметили небольшое перекрытие последних правых ячеек и правую границу элемента td, которая не совмещена должным образом с элементом th. Это связано с тем, что в этой таблице отсутствуют ячейки. Если вы даже добавите пустые ячейки (элементы td) на все недостающие места. Он будет исправлен и будет выглядеть идеально. Его краткое содержание таково: «Убедитесь, что количество td в каждом элементе tr соответствует количеству элементов th, находящихся в элементе thead».

Это не работает. Вертикальная полоса прокрутки остается на теле, но не прокручивает таблицу. Свиток таблицы просто скрыт. Также не исправлена ​​горизонтальная прокрутка, прокручивающая таблицу.

happy_story 15.04.2024 16:25

Я обновил свой ответ. Можете ли вы проверить его еще раз?

Abdur Rehman 15.04.2024 16:52

Спасибо! Есть ли способ предотвратить перемещение «компонентов» второго столбца при использовании горизонтальной полосы прокрутки? Кроме того, тот же вопрос касается строк, когда вы используете вертикальную полосу прокрутки. Есть небольшое движение, а также небольшой зазор между столом и столом.

happy_story 16.04.2024 09:08

Извините, но я не на 100% понял то, что вы пытаетесь сказать. И все же есть кое-что, что я могу вам сказать. Если вы хотите удалить небольшой пробел над первой строкой элементов «th», вы можете добавить transform: translateY(-1px); ко всем элементам th в заголовке. Это устранит небольшой зазор над строкой. Во-вторых, чтобы остановить перемещение столбца «компонент», вы можете изменить левое значение CSS «второго столбца» на (149 или 150), чтобы предотвратить его перемещение по горизонтали. Надеюсь это поможет!

Abdur Rehman 16.04.2024 10:07

Итак, теперь есть 3 проблемы. Во-первых, когда я перемещаю горизонтальную полосу прокрутки, границы td тоже прокручиваются, и в первых двух столбцах открывается пробел, потому что их границы перемещаются вместе с полосой прокрутки! Есть ли способ предотвратить это? Я обновил вопрос, чтобы показать вам скриншот того, что я имею в виду. Вторая проблема заключается в том, что то же самое происходит с нижней границей. Когда я прокручиваю вертикальную прокрутку вниз, верхняя и нижняя граница столбцов скрывается, потому что острота перемещается вместе с прокруткой. Также присутствует на скриншоте. Третья проблема заключается в том, что при прокрутке происходит небольшое движение.

happy_story 16.04.2024 10:59

Уф! Я обновил свой ответ в соответствии с вашими новыми требованиями. Проверьте фрагмент, если он соответствует вашим условиям и работает нормально. 😮‍💨

Abdur Rehman 16.04.2024 12:01

Кажется, это работает над фрагментом. Ваши новые изменения сопровождаются комментариями? Я спрашиваю, чтобы не копировать/вставлять все снова. Я просто хочу добавить новые изменения.

happy_story 16.04.2024 12:04

Мой английский не слишком хорош, но я понимаю. Да, я обновил код как ответ на 3 проблемы, которые вы задали в комментариях. Разве это не так?

Abdur Rehman 16.04.2024 12:09

Да, те, что с комментарием, — это мои новые изменения

Abdur Rehman 16.04.2024 12:10

Давайте продолжим обсуждение в чате.

Abdur Rehman 16.04.2024 12:25

Другие вопросы по теме