【问题标题】:Stack children vertically in left/right columns without vertical white-space在左/右列中垂直堆叠子级,没有垂直空白
【发布时间】:2022-01-26 05:12:24
【问题描述】:

我正在尝试将容器 div 的子项分隔为左/右列,在子项下方或上方没有垂直空格。

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

设置

我有一个容器,其中包含 <div>s 的子类,其类为 .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>

我需要孩子分两列显示。如果孩子有课程.left,它会在左栏中。如果它有.right,它会出现在右列中。

我需要孩子们从顶部开始填写他们各自的列,每个孩子的上方或下方都没有空格。

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

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

提醒一下,我受限于 (1) 以前的 HTML 结构和 (2) 子 &lt;div&gt; 的高度无法修复。

这是我尝试过的方法,以及为什么它不起作用:

选项 1:CSS 浮动

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

这几乎可行,除非前两个孩子有 .right 类。您可以看到第二个.right 子浮动占据了第一个.right 子的剩余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 网格

我应用了一些 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 孩子的高度大于 .right 孩子时,它会导致 .right 孩子添加空白以填充行。

选项 3:Desandro 砌体

我尝试了 Desandro Masonry 选项,但子项以静态顺序输出,不考虑左/右。而且我还没有在库中找到一个明确的选项,它允许利用一个类并将其分配到基于.right.left 类的列中。

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 无论如何都不会做我需要的事情。但也许我错过了什么?

选项 5:CSS Column-Count 属性

只是为了好玩,我弄乱了 CSS Column-Count 属性,但没有办法将子级分配到左/右列。

===

此时我被卡住了。今天我尝试了这么多变体,读了这么多堆栈,以至于我的大脑都被拉屎了。

我将非常感谢任何能够达到预期结果的想法。我可能只是在我已经尝试过的解决方案之一中遗漏了一些东西。

感谢您的宝贵时间!

【问题讨论】:

  • 这是一个测验吗?只需为每列添加两个 div 并完成,如果您被允许更改 HTML 哈哈
  • 如果你能在试用版中使用 JS 库,我想你会被允许使用自己的一些 JS 吗?可以吗?
  • css-grid 问题可以使用砌体解决。但这是实验性的,仅在 Firefox 中支持并在标志后面,因此目前还不是解决方案。
  • 是的,我研究了 css-grid masonry 选项并发现了与 FireFox 兼容性相同的事情。不幸的是,我需要广泛的浏览器支持。

标签: css flexbox css-float css-grid jquery-masonry


【解决方案1】:

如果你被允许使用一点 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>

【讨论】:

  • 谢谢!我认为 js 可能是答案,但我的知识有限。它似乎适用于单个容器。我确实有一个问题。在应用它的应用程序中,.container 是一行数据。所以可以有多个 .containers 组成大量的数据行。您可以通过多次复制粘贴 HTML 块并删除/添加一些子项来创建高度变化来模拟我的设置。此解决方案似乎只计算列表中的第一个容器,而不计算其他容器。每个容器的高度由里面的孩子数量决定。
  • 如果您有多个容器,只需使用 querySelectorAll 循环遍历它们。
  • 这似乎在我的应用程序中造成了更多的布局问题。由于我现在超出了这个问题的范围,我将用你的答案将它标记为完成,并继续努力为我的应用程序塑造它。谢谢!
猜你喜欢
  • 2018-05-30
  • 1970-01-01
  • 2019-10-10
  • 2013-11-18
  • 2016-04-19
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
  • 2023-03-26
相关资源
最近更新 更多