17

I have multiple divs with a fixed width and height (think about some sort of catalog view with article pictures). Now I want to show them similar to the behavior of float:left. This ensures that the larger your browser window is, the more divs are shown in one row.

The downside of the float:left solution is, that there is a big white gap on the right side, until another div will fit. Now I have the job to distribute the divs evenly one the page, and instead of a big white gap on the right side, there should be evenly distributed gaps between the single divs.

A solution in JavaScript is easy: http://dl.dropbox.com/u/2719942/css/columns.html

You can see, if you resize the browser window, it behaves similar to float:left, but the space is evenly distributed between the boxes. The column and row count is dynamically calculated with JavaScript:

  function updateLayout() {
    var boxes = document.getElementsByClassName('box');
    var boxWidth = boxes[0].clientWidth;
    var boxHeight = boxes[0].clientHeight;
    var parentWidth = boxes[0].parentElement.clientWidth;

    // Calculate how many boxes can fit into one row
    var columns = Math.floor(parentWidth / boxWidth);

    // Calculate the space to distribute the boxes evenly
    var space = (parentWidth - (boxWidth * columns)) / columns;

    // Now let's reorder the boxes to their new positions
    var col = 0;
    var row = 0;
    for (var i = 0; i < boxes.length; i++) {
      boxes[i].style.left = (col * (boxWidth + space)) + "px";
      boxes[i].style.top = (row * boxHeight) + "px";

      if (++col >= columns) {
        col = 0;
        row++;
      }
    }
  }

Now I wonder if there is a solution without JavaScript? I would prefer a CSS-only solution, because I will have possibly up to hundreds of divs on one page.

I looked into CSS3 Flexible Box Layout, but this seems to be only useful for fixed column layouts. In my example, the column count gets calculated dynamically. Then I tried CSS3 Multi-column Layout, which I could get something similar working, but the divs are aligned vertically, cut off in the inside, and the browser support isn't there yet. This seems more useful for text, but in my case I have fixed divs with pictures, that shouldn't get cut off.

So my question is: can I realize something like this without JavaScript?

4

4 回答 4

13

最接近的纯 CSS 解决方案是基于text-align: justify.

这是我展示该技术的两个答案:

这是使用您的 HTML/CSS 的演示:http: //jsfiddle.net/thirtydot/5CJ5e/(或全屏

如果与其他行相比有不同数量的框,则您的 JavaScript 和此 CSS 处理最后一行的方式会有所不同。

你的 JavaScript 会这样做:

我的 CSS 这样做:

如果 CSS 对最后一行的不同数量的框所做的操作是不可接受的,您可以添加一些额外的不可见框来完成该行:

http://jsfiddle.net/thirtydot/5CJ5e/1/(或全屏

这样做的问题是不可见的框会增加包含元素的高度。如果这是一个问题,我想不出不使用一点 JavaScript 的方法来解决它:

http://jsfiddle.net/thirtydot/5CJ5e/2/(或全屏

当然,既然现在正在使用 JavaScript,那么您不妨首先使用它来添加不可见的框(而不是玷污 HTML):

http://jsfiddle.net/thirtydot/5CJ5e/5/(或全屏

我还在早期版本中为此编写了一个更复杂的 JavaScript 修复程序,在我想到隐形框的想法之前。现在应该没有理由使用我的旧修复程序。)

于 2012-05-11T11:41:37.567 回答
5

您将需要使用 Javascript 来执行此操作。

但只需调整框类即可一次调整所有框的边距。

// Calculate how many boxes can fit into one row
var columns = Math.floor(parentWidth / boxWidth);

// Calculate the space to distribute the boxes evenly
var space = (parentWidth - (boxWidth * columns)) / columns;

$('.boxClass').css('margin', space / 2);

-

示例:http: //jsfiddle.net/VLr45/1/

于 2012-05-11T09:12:38.570 回答
2

也许MASONRY可以帮助安置?

于 2012-05-11T09:41:29.700 回答
1

所以我的问题是:我可以在没有 JavaScript 的情况下实现这样的事情吗?

我最近进行了同样的练习,最后放弃并使用了 JavaScript。即使放弃 IE 7 和 8(这不切实际),我也找不到纯 CSS 解决方案。我想您可以将一长串媒体查询组合在一起,以有限的方式完成此任务。

我最终写了一个小(大约 1K 缩小)库来处理宽度、高度、比例缩放、最大宽度、滚动、一致的边距和填充等。

这是使用我自己的代码的粗略示例:http: //jsfiddle.net/CmZju/2/。我在示例中放置了几百个元素。

我更喜欢纯 CSS 的解决方案,因为我可能会在一个页面上拥有多达数百个 div。

浏览器的布局引擎必须执行与您相同(或相似)的计算。当然,它是高度优化的,但我会在几台旧 PC 和几台移动设备上测试你的 JS 解决方案,然后再认为它太慢了。

看起来您正在使用绝对定位。我的非正式测试显示绝对布局比浮点计算快得多。如果您考虑浏览器必须做的工作来计算相对大小和浮动的项目,而不是仅在特定位置绘制具有特定尺寸的元素,这是有道理的。

如果你真的想着眼于优化性能,你只能操纵可见的内容。这比仅调整所有内容的大小要困难得多,并且可能仅在页面上有数千个项目时才相关。

如果您最终选择了脚本路线,您可能需要查看jQuery Masonry以获得更多想法。我听说过关于它的好消息,它给了我一些关于我自己的图书馆的好主意。

于 2012-05-11T09:13:04.713 回答