CSS中不同高度块的垂直对齐

4

我想要实现与这个相似的效果。也就是说,我有一些块(这里是文章),它们具有相同的宽度但可以具有不同的高度,并且我希望它们紧贴它们上方的邻居。在内联显示文章并使用顶部垂直对齐时,文章仍然按预期留在它们的行上:

<html>
<head>
<style>
  article { display: inline-block; vertical-align: top; width:200px; margin:5px; background-color:#D0D0D0; }
</style>
</head>
<body>
<div style="width:630px; background-color:#F0F0F0">
<article style="height:100px;"></article><article style="height:200px;"></article><article style="height:300px;"></article><article style="height:200px;"></article><article style="height:200px;"></article><article style="height:100px;"></article>
</div>
</body>
</html>

我猜如果我将文章设置为预定义列,然后在这些列内垂直对齐会更容易些,但据我所知,上述示例不是这种情况(可能具有动态更改列数的优点)。
在CSS中是否可以实现这一点?还是他们使用一些复杂的JavaScript来实现?
(此外,需要将articles并排放置,以防止出现杂乱的空格,但在上述页面中似乎没有这个问题。)
编辑
我未能提到的页面的一个重要行为是,文章的显示顺序与它们的列表顺序基本相同,因此例如保留了时间顺序。

1
你提供的示例(blaskdemo)使用JavaScript检测最高的下一个空闲位置,然后使用内联样式(例如`style="position: absolute; left: 349px; top: 252px; opacity: 1;")将下一篇文章放置在那里。我怀疑这不能用纯CSS实现。 - klaar
3个回答

5
这里有几个选项,这完全取决于您想要块的顺序和元素之间的空间。
您可以在下面的脚本中看到所有技术的实际应用。
简而言之,CSS可能不足以支持此处需求。
首先让我们看看所有可能有帮助的CSS技术。
- display: inline-block; - display: table; - Floats - columns - flexbox
display: inline-block允许您控制垂直对齐方式。并且顺序是从左到右。但空间未得到充分利用。
display: table的行为与inline-block大致相同(取决于设置),但在这里作用不大。
floats:使用空间更好。但它的行为有点奇怪。(尝试在DOM中切换元素。)
columns:非常好地利用了空间。但顺序基于列,而不是文本方向。并且您可能会遇到一些webkit特定的错误。

flexbox:可以为您做很多事情。在这里控制顺序是棘手的,因为换行基于列。否则它会类似于inline-block;

JS也能解决问题。

我不想承认,但JavaScript可能是这里的正确选择。有一些称为isotope或masonry的东西可以使用。这样顺序就基于文本方向,并且空间得到了充分利用。

...

还有其他CSS技术可供使用,可能会获得更好的结果。 但是现在这些技术的浏览器支持有限:

$(function(){
  $('.masonry').masonry({
    // options
    itemSelector : '.masonry article'});
});
hr  {
 clear: left; 
}

article {
  width: 32%;
  margin-top: 15px;
  
  color: #fff;
  font-size: 20px;
}

.inline-block article {
  display: inline-block;
  vertical-align: top;
}

.float article {
  float: left;
  width: 32%;
  margin-left: 3px;  
}

.columns {
  -webkit-column-count: 3;
     -moz-column-count: 3;
          column-count: 3;

  -webkit-column-gap: 0;
     -moz-column-gap: 0;
          column-gap: 0;
}
  .columns  article{
     width: 100%;
  }

.flexbox {
  display: flex; 
  flex-direction: column; 
  flex-wrap: wrap;
  max-height: 500px;
}
  .flexbox article {
    margin-left: 3px;  
  }

.masonry article {
  margin-left: 3px;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://desandro.github.io/masonry/jquery.masonry.min.js"></script>

Inline-block: 
<div class="inline-block">
  <article style="height:300px;background:red">1</article>
  <article style="height:100px; background:blue">2</article>
  <article style="height:200px;background:green">3</article>  
  <article style="height:100px;background:orange">4</article>
  <article style="height:200px;background:purple">5</article>
  <article style="height:200px;background:black">6</article> 
</div>

<hr />

Floats: 
<div class="float">
  <article style="height:300px;background:red">1</article>
  <article style="height:100px; background:blue">2</article>
  <article style="height:200px;background:green">3</article>  
  <article style="height:100px;background:orange">4</article>
  <article style="height:200px;background:purple">5</article>
  <article style="height:200px;background:black">6</article>   
</div>

<hr />

Columns: 
<div class="columns">
  <article style="height:300px;background:red">1</article>
  <article style="height:100px; background:blue">2</article>
  <article style="height:200px;background:green">3</article>  
  <article style="height:100px;background:orange">4</article>
  <article style="height:200px;background:purple">5</article>
  <article style="height:200px;background:black">6</article>   
</div>

<hr />

Flexbox: 
<div class="flexbox">
  <article style="height:300px;background:red">1</article>
  <article style="height:100px; background:blue">2</article>
  <article style="height:200px;background:green">3</article>  
  <article style="height:100px;background:orange">4</article>
  <article style="height:200px;background:purple">5</article>
  <article style="height:200px;background:black">6</article>   
</div>

<hr />

Masonry (JS): 
<div class="masonry">
  <article style="height:300px;background:red">1</article>
  <article style="height:100px; background:blue">2</article>
  <article style="height:200px;background:green">3</article>  
  <article style="height:100px;background:orange">4</article>
  <article style="height:200px;background:purple">5</article>
  <article style="height:200px;background:black">6</article>   
</div>


4
您可以使用 CSS 列。

div {
  width: 630px;
  background-color: #F0F0F0
}
div {
  -webkit-column-count: 3;
  -moz-column-count: 3;
  column-count: 3;
  -webkit-column-gap: 0;
  -moz-column-gap: 0;
  column-gap: 0;
}
<div>
  <article style="height:100px; background:blue"></article>
  <article style="height:200px;background:green"></article>
  <article style="height:300px;background:red"></article>
  <article style="height:200px;background:purple"></article>
  <article style="height:200px;background:black"></article>
  <article style="height:100px;background:orange"></article>
</div>


很好的解决方案,但由于填充列的顺序不同于我提供的示例,因此并不等同。我将编辑我的问题以明确这一点。 - P-Gn

3

我已经尝试了许多不同的CSS方法,但我个人认为(虽然不想说)仅使用CSS是不可能实现这一点的。

Flexbox、Grids、Columns、Table-Layouts和浮动等技术都无法解决这个特定的布局问题。

最接近的方法可能是使用flexbox或浮动结合clearfixes。然而,当您的网站响应式时,将遇到很多布局问题。

根本问题在于您事先不知道容器的高度。您必须计算高度并重新排列其他所有容器(并且您必须针对每个在未来/过去创建的容器进行此操作)。

因此,您可以尝试使用CSS,并且您可能会接近(通过忽略旧浏览器,CSS中的nth-child选择器可以为您完成),但您无法达到您提供的演示(blaskdemo)中布局与那么灵活的程度 - 遗憾的是确实如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接