Невозможно одновременно получить липкую строку и столбец из-за переполнения-x

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

Я использовал display:sticky, и он работал как положено, пока я не активировал overflow-x:scroll в правой части таблицы. Судя по всему, эти два стиля сталкиваются и приводят к нежелательному результату. Проблема решена путем переноса внутренней разметки в раздел, который можно прокручивать по вертикали. К сожалению, это исключает возможность горизонтальной прокрутки, ограниченной нужным набором столбцов. Теперь вся таблица прокручивается горизонтально (включая левые столбцы, которые должны быть фиксированными).

Вот рабочий пример, иллюстрирующая «к сожалению» решенную проблему.

Как я могу подойти к этому наилучшим образом?

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

Однако это приводит к проблеме, связанной с тем, что верхний/нижний колонтитул наложения не прилипает при вертикальной прокрутке, и мы возвращаемся к квадрату 0. В скрипте это можно отобразить, изменив стиль display на flex вместо none и компонент имеет идентификатор fixy.

#fixy {
  display: none;
  border-color: fuchsia;
  position: sticky;
  left: 0;
  top: 0;
  overflow: hidden;
  z-index: 10;
}

#fixy .cell {
  background-color: teal;
  color: white;
  font-weight: bold;
}

Образ желаемого идеального состояния. Левая стрелка указывает на курсор текущей горизонтальной прокрутки. Стрелка вправо указывает на желаемую ширину/расположение всей прокрутки.

HTML

<div class = "section">

  <div id = "fixy" class = "table left">

    <div class = "header">
      <div class = "cell wide">left head 1</div>
      <div class = "cell wide">left head 2</div>
    </div>

    <div class = "row">
      <div class = "cell wide">val1a</div>
      <div class = "cell wide">val1b</div>
    </div>
    <div class = "row">
      <div class = "cell wide">val2a</div>
      <div class = "cell wide">val2b</div>
    </div>
    <div class = "row">
      <div class = "cell wide">val3a</div>
      <div class = "cell wide">val3b</div>
    </div>

    <div class = "footer">
      <div class = "cell wide">left foot 1</div>
      <div class = "cell wide">left foot 2</div>
    </div>

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

    <div class = "header">
      <div class = "cell wide">left head 1</div>
      <div class = "cell wide">left head 2</div>
    </div>

    <div class = "row">
      <div class = "cell wide">val1a</div>
      <div class = "cell wide">val1b</div>
    </div>
    <div class = "row">
      <div class = "cell wide">val2a</div>
      <div class = "cell wide">val2b</div>
    </div>
    <div class = "row">
      <div class = "cell wide">val3a</div>
      <div class = "cell wide">val3b</div>
    </div>

    <div class = "footer">
      <div class = "cell wide">left foot 1</div>
      <div class = "cell wide">left foot 2</div>
    </div>
  </div>

  <div class = "table right">

    <div class = "header">
      <div class = "cell fixed">right head 1</div>
      <div class = "cell fixed">right head 2</div>
      <div class = "cell fixed">right head 3</div>
      <div class = "cell fixed">right head 4</div>
      <div class = "cell fixed">right head 5</div>
    </div>

    <div class = "row">
      <div class = "cell fixed">cont1</div>
      <div class = "cell fixed">cont2</div>
      <div class = "cell fixed">cont3</div>
      <div class = "cell fixed">cont4</div>
      <div class = "cell fixed">cont5</div>
    </div>
    <div class = "row">
      <div class = "cell fixed">cont1</div>
      <div class = "cell fixed">cont2</div>
      <div class = "cell fixed">cont3</div>
      <div class = "cell fixed">cont4</div>
      <div class = "cell fixed">cont5</div>
    </div>
    <div class = "row">
      <div class = "cell fixed">cont1</div>
      <div class = "cell fixed">cont2</div>
      <div class = "cell fixed">cont3</div>
      <div class = "cell fixed">cont4</div>
      <div class = "cell fixed">cont5</div>
    </div>

    <div class = "footer">
      <div class = "cell fixed">right foot 1</div>
      <div class = "cell fixed">right foot 2</div>
      <div class = "cell fixed">right foot 3</div>
      <div class = "cell fixed">right foot 4</div>
      <div class = "cell fixed">right foot 5</div>
    </div>
  </div>
</div>

CSS

* {
  border-width: 1px;
  border-style: solid;
}

div.section {
  border-color: pink;
  width: 600px;
  height: 300px;
  display: flex;
  overflow: scroll;
  flex-direction: row;
  position: relative;

  align-items: flex-start;
  justify-content: stretch;
}

#fixy {
  display: none;
  border-color: fuchsia;
  position: sticky;
  left: 0;
  top: 0;
  overflow: hidden;
  z-index: 10;
}

#fixy .cell {
  background-color: teal;
  color: white;
  font-weight: bold;
}

div {
  display: flex;
  white-space: nowrap;
}

div.left {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;

  border-color: blue;
  min-width: 300px;
  max-width: 300px;
  flex: 0 0 0;

}

div.right {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;

  border-color: green;
  flex: 1 1 0;
}

div.header {
  border-color: orange;
  flex-direction: row;
  min-height: 90px;
  max-height: 90px;
  position: sticky;
  top: 0;
}

div.row {
  border-color: pink;
  flex-direction: row;
  min-height: 60px;
  max-height: 60px;
  flex: 1 1 1;
}

div.footer {
  border-color: purple;
  flex-direction: row;
  min-height: 90px;
  max-height: 90px;
  position: sticky;
  bottom: 0;
}

div.cell {
  background-color: yellow;
  align-items: center;
  padding: 10px;
}

div.wide {
  flex: 1 1 0;
  background-color: azure;
}

div.fixed {
  width: 100px;
  min-width: 100px;
}

🤔 А знаете ли вы, что...
HTML (HyperText Markup Language) - это стандартный язык разметки для создания веб-страниц.


363
1

Ответ:

Решено

Судя по вашему вопросу, я думаю, что вам нужно что-то вроде freeze в Excel.

Попробуйте добавить этот стиль

* {
  border-width: 1px;
  border-style: solid;
}

div.section {
  border-color: pink;
  width: 600px;
  height: 300px;
  display: flex;
  overflow: scroll;
  flex-direction: row;
  position: relative;

  align-items: flex-start;
  justify-content: stretch;
}

#fixy {
  display: none;
  border-color: fuchsia;
  position: sticky;
  left: 0;
  top: 0;
  overflow: hidden;
  z-index: 10;
}

#fixy .cell {
  background-color: teal;
  color: white;
  font-weight: bold;
}

div {
  display: flex;
  white-space: nowrap;
}

div.left {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;

  border-color: blue;
  min-width: 300px;
  max-width: 300px;
  flex: 0 0 0;

}

div.right {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;

  border-color: green;
  flex: 1 1 0;
}

div.header {
  border-color: orange;
  flex-direction: row;
  min-height: 90px;
  max-height: 90px;
  position: sticky;
  top: 0;
}

div.row {
  border-color: pink;
  flex-direction: row;
  min-height: 60px;
  max-height: 60px;
  flex: 1 1 1;
}

div.footer {
  border-color: purple;
  flex-direction: row;
  min-height: 90px;
  max-height: 90px;
  position: sticky;
  bottom: 0;
}

div.cell {
  background-color: yellow;
  align-items: center;
  padding: 10px;
}

div.wide {
  flex: 1 1 0;
  background-color: azure;
}

div.fixed {
  width: 100px;
  min-width: 100px;
}
.table.left
{
  position: sticky;
  left:0;
  top:0;
  z-index:10
}

все, что я сделал, это добавил это к твоему стилю

.table.left
{
  position: sticky;
  left:0;
  top:0;
  z-index:10
}

Проверьте: https://jsfiddle.net/p1Lr0fb9/

.section {
  -ms-overflow-style: none; /* for Internet Explorer, Edge */
  scrollbar-width: none; /* for Firefox */
  overflow-y: scroll;
}
.section::-webkit-scrollbar {
  display: none; /* for Chrome, Safari, and Opera */
}

.right,.row
{
   cursor:all-scroll;
}

Добавлен CSS для скрытия полосы прокрутки и индикатор прокрутки курсора.