在仅包含图像的列数CSS列中平衡高度

Fau*_* NA 21 html javascript css

我正在尝试使用以下代码平衡图像库中列之间的高度:

section {
    background: magenta;
    /* So you can see the area I don't want to appear */
}

.gallery {
    width: 100%;
    line-height: 0;
    -webkit-column-count: 2;
    -webkit-column-gap: 0;
    -moz-column-count: 2;
    -moz-column-gap: 0;
    column-count: 2;
    column-gap: 0;
}
Run Code Online (Sandbox Code Playgroud)
<section class="gallery">
    <div>
        <img src="http://lorempixel.com/800/1000/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/600/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/200/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/700/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/900/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/400/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/200/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/600/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/700/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/600/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/550/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/700/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/600/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/1000/">
    </div>
    <div>
        <img src="http://lorempixel.com/800/700/">
    </div>
</section>
Run Code Online (Sandbox Code Playgroud)

这是一个JSFiddle:https://jsfiddle.net/auan2xnj/1/

图像都具有不同的高度,但都具有相同的宽度.我column-fill被设置为balance(默认情况下).

问题:

在JSFiddle中,它看起来相当不错,但在我正在开发的网站上,比较列的高度出现了一些巨大的差距.我猜这是因为图像在HTML中的顺序,考虑到它们将被CSS放入列中的完全相同的顺序.这是我的项目的截图,使用与JSFiddle完全相同的代码:

在此输入图像描述

行为:

当我给.gallery元素一个硬编码height值时,列总是更好地平衡.这是一个问题,因为在我的网站中,图像是动态添加的,我永远不会知道所有画廊的确切高度.

请求:

我想找到一段代码(无论是什么,我认为我可以实现一些JS)来修复这个问题,要么通过重新排序HTML中的图像以便结果是最好的,或者以任何方式存在以动态设置高度,以解决问题.

Cod*_*rPi 9

编辑: 如果您不需要保留line-height: 0,只需使用.gallery img {display:block}和删除行高,这就是您所需要的.那将是最好的.table-cell等可能会产生一些副作用.例如vertical-align: middle,在图像下面留一个空间,只是一个黑客.

https://jsfiddle.net/bruLwktv/


Challange接受了,这是解决方案:;)

该算法确保每个图像都被加载,然后将它们分成两个颜色,使得最接近的总高度可以创建最小间隙.

使用分区问题的贪婪算法创建平衡分区.

var gallery = document.getElementsByClassName("gallery")[0]
var images = gallery.getElementsByTagName("img")
var notLoaded = 0

window.onload = function() {
  for (var i = images.length; i--;) {
    if (images[i].width == 0) {
      // let the image tell us when its loaded
      notLoaded++
      images[i].onload = function() {
        if (--notLoaded == 0) {
          allImgLoaded()
        }
      }
    }
  }
  // check if all images are already loaded
  if (notLoaded == 0) allImgLoaded()
}

function allImgLoaded() {
  // Partition images
  var imgs = partitionImages(images)
  // reorder DOM
  for (var i = images.length; i--;) {
    gallery.appendChild(imgs[i])
  }
}

function partitionImages(images) {
  var groupA = [], totalA = 0
  var groupB = [], totalB = 0

  // new array width img and height
  var imgs = []
  for (var i = images.length; i--;) {
    imgs.push([images[i], images[i].height])
  }
  // sort asc
  imgs.sort(function(a, b) {
    return b[1] - a[1]
  });
  // reverse loop
  for (var i = imgs.length; i--;) {
    if (totalA < totalB) {
      groupA.push(imgs[i][0])
      totalA += imgs[i][1]
    } else {
      groupB.push(imgs[i][0])
      totalB += imgs[i][1]
    }
  }

  return groupA.concat(groupB)
}
Run Code Online (Sandbox Code Playgroud)
section {
  background: magenta;
  /* So you can see the area I don't want to appear */
}
.gallery {
  width: 100%;
  line-height: 0;
  -webkit-column-count: 2;
  -webkit-column-gap: 0;
  -moz-column-count: 2;
  -moz-column-gap: 0;
  column-count: 2;
  column-gap: 0;
}
Run Code Online (Sandbox Code Playgroud)
<section class="gallery">
  <div><img src="http://lorempixel.com/800/1000/"></div>
  <div><img src="http://lorempixel.com/800/600/"></div>
  <div><img src="http://lorempixel.com/800/200/"></div>
  <div><img src="http://lorempixel.com/800/700/"></div>
  <div><img src="http://lorempixel.com/800/900/"></div>
  <div><img src="http://lorempixel.com/800/400/"></div>
  <div><img src="http://lorempixel.com/800/200/"></div>
  <div><img src="http://lorempixel.com/800/600/"></div>
  <div><img src="http://lorempixel.com/800/700/"></div>
  <div><img src="http://lorempixel.com/800/600/"></div>
  <div><img src="http://lorempixel.com/800/550/"></div>
  <div><img src="http://lorempixel.com/800/700/"></div>
  <div><img src="http://lorempixel.com/800/600/"></div>
  <div><img src="http://lorempixel.com/800/1000/"></div>
  <div><img src="http://lorempixel.com/800/700/"></div>
</section>
Run Code Online (Sandbox Code Playgroud)