CSS-layout: вертикальный скролл контейнера и горизонтальный скролл вложенного блока без JS

Задача сделать контейнер, в котором будет 2 скролла (вертикальный и горизонтальный у вложенного блока).

#container - контейнер который содержит 2 блока (левая и правая панель)
.left - левая панель
.right - правая панель

#container имеет overflow-y: auto что позволяет вертикально скроллить внутренний контент, который будет выше самого контейнера. .left и .right всегда будут иметь идентичную высоту и если мы будет скроллить вертикально #container то оба блока (.left и .right) будут идентично передвигаться.

.right должен иметь горизонтальный скролл, и этот горизонтальный скролл будет всегда в самом низу блока, и что бы его увидеть то придется вертикальный скролл в #container проскролить в самый низ. Для того что бы этот горизонтальный скролл был всегда виден - пришлось к .right добавить position: sticky; top: 0; и заблокировать ему вертикальный скролл overflow-y: hidden, но горизонтальный скролл разрешен overflow-x: auto

И так как теперь у меня в .right вертикальный скролл заблокирован, то мне приходится обновлять его на основе вертикального скролла в #container с помощью пару строк в JS

Вот как все выглядит в собранном виде

let container = document.getElementById("container")
let right = document.querySelector(".right")
container.addEventListener("scroll", (e) => {
  right.scrollTop = e.target.scrollTop
})
html, body {
  height: 100%;
  margin: 0;
}

#container {
  width: 600px;
  height: 100%;
  max-height: 300px;
  background: rgba(0, 0, 0, 0.1);
  overflow-y: auto;
  
  display: flex;
  
  position: relative;
}

.left {
  width: 200px;
  min-height: 100%;
  height: 100%;
  border-right: 1px solid red;
  
  display: flex;
  flex-direction: column;
  row-gap: 10px;
}

.right {
  width: 400px;
  overflow-x: auto;
  overflow-y: hidden;
  
  display: flex;
  flex-direction: column;
  row-gap: 10px;
  
  position: sticky;
  top: 0;
}

p {
  background: blue;
  color: #fff;
  padding: 10px;
  margin: 0;
}

.right p {
  width: 600px;
  background: royalblue;
  text-align: center;
}
<div id="container">
  <div class="left">
    <p>Task 0</p>
    <p>Task 1</p>
    <p>Task 2</p>
    <p>Task 3</p>
    <p>Task 4</p>
    <p>Task 5</p>
    <p>Task 6</p>
    <p>Task 7</p>
    <p>Task 8</p>
    <p>Task 9</p>
  </div>
  <div class="right">
    <p>Task 0</p>
    <p>Task 1</p>
    <p>Task 2</p>
    <p>Task 3</p>
    <p>Task 4</p>
    <p>Task 5</p>
    <p>Task 6</p>
    <p>Task 7</p>
    <p>Task 8</p>
    <p>Task 9</p>
  </div>
</div>

Вопрос: можно ли как то получить идентичный результат без использования JS? (возможно надо будет немного изменить структуру HTML)

Вот еще код на codepen: https://codepen.io/unnxkcpk-the-looper/pen/dPMMEvW


Ответы (1 шт):

Автор решения: Qwertiy

Не знаю, подходит ли это решение, но я рекомендую сделать оба скролла у контейнера, а левый блок держать на месте с помощью position: sticky.

html, body {
  height: 100%;
  margin: 0;
}

#container {
  width: 600px;
  height: 100%;
  max-height: 300px;
  background: rgba(0, 0, 0, 0.1);
  overflow: auto;
  
  display: flex;
  
  position: relative;
}

.left {
  width: 200px;
  min-height: 100%;
  height: 100%;
  border-right: 1px solid red;
  
  position: sticky;
  left: 0;
  
  display: flex;
  flex-direction: column;
  row-gap: 10px;
}

.right {
  width: 400px;
  
  display: flex;
  flex-direction: column;
  row-gap: 10px;
}

p {
  background: blue;
  color: #fff;
  padding: 10px;
  margin: 0;
}

.right p {
  width: 600px;
  background: royalblue;
  text-align: center;
}
<div id="container">
  <div class="left">
    <p>Task 0</p>
    <p>Task 1</p>
    <p>Task 2</p>
    <p>Task 3</p>
    <p>Task 4</p>
    <p>Task 5</p>
    <p>Task 6</p>
    <p>Task 7</p>
    <p>Task 8</p>
    <p>Task 9</p>
  </div>
  <div class="right">
    <p>Task 0</p>
    <p>Task 1</p>
    <p>Task 2</p>
    <p>Task 3</p>
    <p>Task 4</p>
    <p>Task 5</p>
    <p>Task 6</p>
    <p>Task 7</p>
    <p>Task 8</p>
    <p>Task 9</p>
  </div>
</div>

→ Ссылка