在 left/right 列中垂直堆叠 children 而不垂直 white-space

Stack children vertically in left/right columns without vertical white-space

我正在尝试将容器 div 的 children 分成 left/right 列,children 项目下方或上方没有垂直空白。

我将解释设置并提供所需结果的图片,然后我将解释我尝试过的每个解决方案以及每个解决方案似乎不起作用的原因。

设置

我有一个装有 children <div> 的容器,其 class 为 .left.right。这是代码(我绑定到这个 HTML 结构):

<div class="container">
<div class="right col">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
<div class="right col">R-Pellentesque nec tellus at tellus</div>
<div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
<div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
<div class="col right">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
<div class="left col">L-Pellentesque nec tellus at tellus scelerisque rutrum ut quis nibh. Aliquam nisi nisl, finibus eu condimentum ac, pretium quis augue.</div>
<div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
<div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
</div>

我需要 children 显示在两列中。如果 child 有 class .left,它会出现在左栏中。如果它有 .right,它会出现在右栏中。

我需要 children 从顶部开始填写他们各自的栏目,每个 child.

上方或下方没有 white-space

每个child的高度是由它的文本内容决定的,所以我不能为每个child设置一个固定的高度。

这是期望的结果(为强调而添加的样式): 期望的结果视觉:

提醒一下,我受制于 (1) 之前的 HTML 结构和 (2) child <div> 的高度无法固定。

这是我尝试过的方法,以及它不起作用的原因:

选项 1:CSS浮动

我将每个 child 的 width 设置为 50%,将 display 设置为 inline-block,并将 float:left 应用于 .left children 和 float: right.right children.

这几乎可以工作,除非前两个 children 有一个 .right class。您可以看到第二个 .right child 浮动占据了第一个 .right child.

剩余的 50%

.container > div {color: white; border-bottom: 3px solid white;}

.container {
overflow: auto;
}

.col {
width: 50%;
}


.right {
background: #999;
float: right;
}

.left {
background: #000;
float: left;               
}
<div class="container">
<div class="right col">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
<div class="right col">R-Pellentesque nec tellus at tellus</div>
<div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
<div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
<div class="col right">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
<div class="left col">L-Pellentesque nec tellus at tellus scelerisque rutrum ut quis nibh. Aliquam nisi nisl, finibus eu condimentum ac, pretium quis augue.</div>
<div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
<div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
</div>

选项 2:CSS-Grid

我应用了一些 CSS grid 选项。经过大量研究和反复试验,我能想到的最接近的是:

.container {
display: grid;
grid-template-columns: auto auto;
grid-auto-flow: column;
}


.right {
background: #999;
grid-column-start: 2;
}

.left {
background: #000;
grid-column-start: 1;      
}

.container > div {color: white; border-bottom: 3px solid white;}
<div class="container">
<div class="right col">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
<div class="right col">R-Pellentesque nec tellus at tellus</div>
<div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
<div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
<div class="col right">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
<div class="left col">L-Pellentesque nec tellus at tellus scelerisque rutrum ut quis nibh. Aliquam nisi nisl, finibus eu condimentum ac, pretium quis augue.</div>
<div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
<div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
</div>

同样,这非常接近,甚至解决了选项 1 中指出的问题。但是您会看到 .left child 的高度何时大于 .right child,它会导致 .right child 添加 white-space 来填充该行。

选项 3:Desandro Masonry

我尝试了 Desandro Masonry 选项,但是 children 以静态顺序输出,与 left/right 无关。而且我还没有在库中找到一个明确的选项,允许利用 class 并将其分配到基于 .right.left class.[= 的列中47=]

var msnry = new Masonry( '.container', {
            itemSelector: '.col',
            });
.container {
display: grid;
}

.col {
width: 50%;
}

.container > div {color: white; border-bottom: 3px solid white;}

.right {
background: #999;
}

.left {
background: #000;      
}
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
<div class="container">
<div class="right col">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
<div class="right col">R-Pellentesque nec tellus at tellus</div>
<div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
<div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
<div class="col right">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
<div class="left col">L-Pellentesque nec tellus at tellus scelerisque rutrum ut quis nibh. Aliquam nisi nisl, finibus eu condimentum ac, pretium quis augue.</div>
<div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
<div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
</div>

选项 4:Flexbox

我尝试了多种 Flexbox 组合,但都无法正常工作。我的研究表明 FlexBox 无论如何都不会做我需要的事情。但也许我遗漏了什么?

选项5:CSS Column-Count 属性

只是为了好玩,我把 CSS Column-Count 属性 弄乱了,但是没有办法将 children 分配给 left/right 列.

===

此时我卡住了。我试了很多变体,今天读了很多书堆,我的脑袋都快烂了。

如果有任何能达到预期结果的想法,我将不胜感激。可能是我在我已经尝试过的解决方案之一中遗漏了一些东西。

感谢您的宝贵时间!

如果你被允许使用一点 JS(我假设你是因为你的一个试验包括一个 jquery 库)你可以计算每个元素的垂直位置,绝对定位每个元素,并且如果容器的相对定位很重要,最后设置容器的高度。

let leftH = 0;
let rightH = 0;
const els = document.querySelectorAll('.container > *');
els.forEach(el => {
  if (el.getAttribute('class').includes('left')) {
    el.style.top = leftH + 'px';
    leftH += el.offsetHeight;
  } else {
    el.style.top = rightH + 'px';
    rightH += el.offsetHeight;
  }

});
document.querySelector('.container').style.height = ((leftH > rightH) ? leftH : rightH) + 'px';
.container {
  width: 100vw;
  position relative;
}

.container>* {
  width: 50%;
  border: 1px solid;
  position: absolute;
}

.right {
  margin-left: 50%;
}
<div class="container">
  <div class="right col">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
  <div class="right col">R-Pellentesque nec tellus at tellus</div>
  <div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
  <div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
  <div class="col right">R-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat odio eget felis mollis placerat. Donec consequat tincidunt nisl sit amet iaculis. In sit amet nisl purus.</div>
  <div class="left col">L-Pellentesque nec tellus at tellus scelerisque rutrum ut quis nibh. Aliquam nisi nisl, finibus eu condimentum ac, pretium quis augue.</div>
  <div class="left col">L-Nulla viverra lorem risus, nec consectetur urna pretium sed. Vestibulum bibendum, tortor vel viverra consequat, urna purus pulvinar odio, sed rutrum justo risus in justo.</div>
  <div class="right col">R-Vivamus in lacus sed dolor ullamcorper blandit non fermentum tortor.</div>
</div>