Добавление вертикально прокручиваемого элемента внутри горизонтальной карусели - PullRequest
4 голосов
/ 21 сентября 2019

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

Код, который я пробовал до сих пор:

html

<div class="carousel">
  <div class="c-item">Item-1</div>
  <!-- to be displayed vertically -->
  <div class="abs">
    <div class="a-item">Abs Item-1.1</div>
    <div class="a-item">Abs Item-1.2</div>
    <div class="a-item">Abs Item-1.3</div>
  </div>
  <div class="c-item margin">Item-2</div>
  <!-- to be displayed vertically -->
  <div class="abs">
    <div class="a-item">Abs Item-2.1</div>
    <div class="a-item">Abs Item-2.2</div>
    <div class="a-item">Abs Item-2.3</div>
  </div>
</div>
<div class="other">
  Other div
</div>

css

.carousel{
  color: #FFF;
  white-space: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  position: initial;
  .c-item{
    display: inline-block;
    width: 35%;
    background: #000;
    height: 100px;
    &.margin{
      //margin-left: 35%;
    }
  }
  .abs{
    background: #444;
    display: inline-block;
    vertical-align: top;
    width: 35%;
    max-height: 180px;
    overflow-y: auto;
    .a-item{
      height: 100px;
      border: 1px solid #000;
    }
  }
}
.other{
  background: yellow;
}

Результат :

enter image description here

( codepen )

Проблема в следующем: я хочу, чтобы другой div запускался чуть ниже item-1;это означает, что вертикально прокручиваемый div должен перекрывать другой div, а высота карусели должна быть установлена ​​на 100px.Я попытался использовать position: absolute для .abs div, но затем этот div не перемещается при прокрутке карусели.


Желаемый вывод будет выглядеть так:

enter image description here

Ответы [ 3 ]

1 голос
/ 21 сентября 2019

Решение Flexbox

  • Каждый элемент имеет 33,33% ширину и 100px высоту. предметов внутри .multiple также 100px high.
  • .multiple имеет position: relative и overflow-y: auto. предметов внутри имеют position: absolute.
  • Подсказка : Контейнер -> position: relative, предметы внутри -> position: absolute.Вот как это работает.
  • top: (100 * n)px для каждого <div> внутри .item.multiple.n - это индекс <div> внутри .item.multiple, начиная с 0.

Структура HTML была изменена

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

.carousel {
  display: flex;
  width: 100vw;
  overflow-x: auto;
  color: white;
}

.carousel>.item {
  flex: 1 0 33.33%;
  //margin-right: 5px;
}

.carousel>.item:nth-child(odd) {
  background: black;
}

.carousel>.item:nth-child(even) {
  background: darkgrey;
}

.carousel>.item,
.carousel>.item.multiple>div {
  height: 100px;
}

.carousel>.item.multiple {
  position: relative;
  overflow-y: auto;
}

.carousel>.item.multiple>div {
  position: absolute;
  width: 100%;
}

.carousel>.item.multiple>div:nth-child(2) {
  top: 100px;
}

.carousel>.item.multiple>div:nth-child(3) {
  top: 200px;
}


/* And so on ... 
.carousel>.item.multiple>div:nth-child(...) {}
*/
<div class="carousel">
  <div class="item">
    <div>Item-1</div>
  </div>
  <div class="item multiple">
    <div>Item-1.1</div>
    <div>Item-1.2</div>
    <div>Item-1.3</div>
  </div>
  <div class="item">
    <div>Item-2</div>
  </div>
  <div class="item multiple">
    <div>Item-2.1</div>
    <div>Item-2.2</div>
    <div>Item-2.3</div>
  </div>
</div>
<div class="other">
  Other div
</div>
0 голосов
/ 27 сентября 2019

Ваш желаемый результат означает, что ребенок перекрывает родителя, и я не думаю, что это возможно.НО вы можете «взломать» это, обернув .carousel другим div (.demo в этом общем примере), так что результаты будут примерно такими:

.demo {overflow: visible; height: 100px;}
.carousel {
  color: #FFF;
  white-space: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  position: initial;
}
.carousel .c-item {
  display: inline-block;
  width: 35%;
  background: #000;
  height: 100px;
}
.carousel .abs {
  background: #444;
  display: inline-block;
  vertical-align: top;
  width: 35%;
  max-height: 180px;
  overflow-y: auto;
}
.carousel .abs .a-item {
  height: 100px;
  border: 1px solid #000;
}
.other {
  background: yellow;
  height: 200px;
}
<div class="demo">
  <div class="carousel">
    <div class="c-item">Item-1</div>
    <div class="abs">
      <div class="a-item">Abs Item-1.1</div>
      <div class="a-item">Abs Item-1.2</div>
      <div class="a-item">Abs Item-1.3</div>
    </div>
    <div class="c-item margin">Item-2</div>
    <div class="abs">
      <div class="a-item">Abs Item-2.1</div>
      <div class="a-item">Abs Item-2.2</div>
      <div class="a-item">Abs Item-2.3</div>
    </div>
  </div>
</div>
<div class="other">
  Other div
</div>

Как видно из фрагмента, скролл-х не отображается - пока он существует.Вы можете щелкнуть один из элементов .carousel и прокрутить их вправо и влево.

Поскольку не очевидно, что .carousel прокручивается, вы можете добавить дополнительные buttons, чтобы прокрутить его:

.demo {overflow: visible; height: 100px;z-index: 3;}
.carousel {
  color: #FFF;
  white-space: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  position: initial;
}
.carousel .c-item {
  display: inline-block;
  width: 35%;
  background: #000;
  height: 100px;
}
.carousel .abs {
  background: #444;
  display: inline-block;
  vertical-align: top;
  width: 35%;
  max-height: 180px;
  overflow-y: auto;
}
.carousel .abs .a-item {
  height: 100px;
  border: 1px solid #000;
}
.other {
  background: yellow;
  height: 200px;
}
<div class="demo">
  <button onclick="document.querySelectorAll('.carousel')[0].scrollLeft += 20;" style="position: fixed; top: 50%; right: 0;">L</button>
  <button onclick="document.querySelectorAll('.carousel')[0].scrollLeft -= 20;" style="position: fixed; top: 50%; left: 0;">R</button>
  <div class="carousel">
    <div class="c-item">Item-1</div>
    <div class="abs">
      <div class="a-item">Abs Item-1.1</div>
      <div class="a-item">Abs Item-1.2</div>
      <div class="a-item">Abs Item-1.3</div>
    </div>
    <div class="c-item margin">Item-2</div>
    <div class="abs">
      <div class="a-item">Abs Item-2.1</div>
      <div class="a-item">Abs Item-2.2</div>
      <div class="a-item">Abs Item-2.3</div>
    </div>
  </div>
</div>
<div class="other">
  Other div
</div>

Надеюсь, это поможет!

0 голосов
/ 25 сентября 2019

Вы должны играть с position проверкой фрагмента.

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

.carousel {
  display: flex;
  width: 100vw;
  overflow-x: auto;
  color: white;
}

.carousel>.item {
  flex: 1 0 33.33%;
  //margin-right: 5px;
}

.carousel>.item:nth-child(odd) {
  background: black;
}

.carousel>.item:nth-child(even) {
  background: darkgrey;
}

.carousel>.item,
.carousel>.item.multiple>div {
  height: 100px;
}

.carousel>.item.multiple {
  position: relative;
  overflow-y: auto;
  height: 200px;
}

.carousel>.item.multiple>div {
  position: absolute;
  width: 100%;
}

.carousel>.item.multiple>div:nth-child(2) {
  top: 100px;
}

.carousel>.item.multiple>div:nth-child(3) {
  top: 200px;
}

.other {
  position: absolute;
  z-index: -1;
  top: 100px;
  width: 100%;
  background: green;
  height: 117px;
}


/* And so on ... 
.carousel>.item.multiple>div:nth-child(...) {}
*/
<div class="carousel">
  <div class="item">
    <div>Item-1</div>
  </div>
  <div class="item multiple">
    <div>Item-1.1</div>
    <div>Item-1.2</div>
    <div>Item-1.3</div>
  </div>
  <div class="item">
    <div>Item-2</div>
  </div>
  <div class="item multiple">
    <div>Item-2.1</div>
    <div>Item-2.2</div>
    <div>Item-2.3</div>
  </div>
</div>
<div class="other">
  Other div
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...