简体   繁体   English

如何使用CSS中的动态列和行计数均匀分布浮动元素?

[英]How to distribute floated elements evenly with a dynamic column and row count in CSS?

I have multiple divs with a fixed width and height (think about some sort of catalog view with article pictures). 我有多个具有固定宽度和高度的div(想想某种带有文章图片的目录视图)。 Now I want to show them similar to the behavior of float:left. 现在我想向他们展示类似于float:left的行为。 This ensures that the larger your browser window is, the more divs are shown in one row. 这样可以确保浏览器窗口越大,一行中显示的div就越多。

The downside of the float:left solution is, that there is a big white gap on the right side, until another div will fit. 浮动的缺点:左边的解决方案是,右侧有一个很大的白色间隙,直到另一个div适合。 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. 现在我的工作是在页面上均匀地分配div,而不是右侧的大白色间隙,单个div之间应该有均匀分布的间隙。

A solution in JavaScript is easy: http://dl.dropbox.com/u/2719942/css/columns.html JavaScript中的解决方案很简单: 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. 您可以看到,如果您调整浏览器窗口的大小,它的行为类似于float:left,但空间均匀分布在框之间。 The column and row count is dynamically calculated with JavaScript: 使用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? 现在我想知道是否有没有JavaScript的解决方案? I would prefer a CSS-only solution, because I will have possibly up to hundreds of divs on one page. 我更喜欢只有CSS的解决方案,因为我在一个页面上可能有多达数百个div。

I looked into CSS3 Flexible Box Layout , but this seems to be only useful for fixed column layouts. 我查看了CSS3 Flexible Box Layout ,但这似乎只适用于固定列布局。 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. 然后我尝试了CSS3多列布局 ,我可以得到类似的工作,但div垂直对齐,在内部切断,浏览器支持还没有。 This seems more useful for text, but in my case I have fixed divs with pictures, that shouldn't get cut off. 这似乎对文本更有用,但在我的情况下,我修复了带图片的div,不应该被切断。

So my question is: can I realize something like this without JavaScript? 所以我的问题是:我可以在没有JavaScript的情况下实现这样的事情吗?

The closest pure CSS solution is based on text-align: justify . 最接近的纯CSS解决方案基于text-align: justify

Here are two of my answers showing the technique: 以下是我的两个答案,显示了该技术:

Here's a demo using your HTML/CSS: http://jsfiddle.net/thirtydot/5CJ5e/ (or fullscreen ) 这是使用HTML / CSS的演示: http//jsfiddle.net/thirtydot/5CJ5e/ (或全屏

There's a difference in the way your JavaScript and this CSS handles the last row if there's a different number of boxes compared to the other rows. 如果与其他行相比存在不同数量的框,则JavaScript和此CSS处理最后一行的方式会有所不同。

Your JavaScript does this: 你的JavaScript做到了这一点:

My CSS does this: 我的CSS做到了这一点:

If what the CSS does with a different number of boxes on the last row is unacceptable, you could add some extra invisible boxes to complete the row: 如果CSS在最后一行上使用不同数量的框执行的操作是不可接受的,则可以添加一些额外的不可见框来完成该行:

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

Doing this has the issue that the invisible boxes increase the height of the containing element. 这样做的问题是隐形框增加了包含元素的高度。 If this is a problem, I can't think of a way to fix it without using a little JavaScript: 如果这是一个问题,我想不出一种方法来修复它而不使用一点JavaScript:

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

Of course, since JavaScript is now being used, you might as well use it to add the invisible boxes in the first place (instead of sullying the HTML): 当然,既然现在正在使用JavaScript,那么您最好使用它来添加不可见的框(而不是隐藏HTML):

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

( I also wrote a more complicated JavaScript fix for this in an earlier revision, before the idea of invisible boxes was brought to me. There should be no reason to use my old fix now.) 我还在早期版本中写了一个更复杂的JavaScript修复程序 ,然后才给我看隐形框的想法。现在应该没有理由使用我的旧修复。)

You will need to use Javascript to do this. 您需要使用Javascript来执行此操作。

But just adjust the box class to adjust the margins of all the boxes at once. 但只需调整框类即可立即调整所有框的边距。

// 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);

- -

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

也许MASONRY可以帮助安置?

So my question is: can I realize something like this without JavaScript? 所以我的问题是:我可以在没有JavaScript的情况下实现这样的事情吗?

I went through the same exercise recently and finally gave up and used JavaScript. 我最近经历了同样的练习,最后放弃并使用了JavaScript。 Even abandoning IE 7 and 8 (which isn't practical) I couldn't find a pure CSS solution. 即使放弃IE 7和8(这是不实际的)我也找不到纯CSS解决方案。 I guess you could hack together a long list of media queries to accomplish this in a limited fashion. 我想你可以将一长串媒体查询整合在一起,以有限的方式实现这一目标。

I ended up writing a little (about 1K minified) library which handles width, height, proportionate scaling, max widths, scrolling, consistent margins and padding, etc. 我最后写了一个小(约1K缩小)库,它处理宽度,高度,比例缩放,最大宽度,滚动,一致的边距和填充等。

Here is a rough example using my own code: http://jsfiddle.net/CmZju/2/ . 这是一个使用我自己的代码的粗略示例: http//jsfiddle.net/CmZju/2/ I've placed a couple hundred elements in the example. 我在示例中放置了几百个元素。

I would prefer a CSS-only solution, because I will have possibly up to hundreds of divs on one page. 我更喜欢只有CSS的解决方案,因为我在一个页面上可能有多达数百个div。

The layout engine of the browser will have to perform the same (or similar) calculations that you do. 浏览器的布局引擎必须执行与您相同(或类似)的计算。 Granted, it is highly optimized but I would test your JS solution on a few old PCs and a few mobile devices before discounting it as too slow. 当然,它是高度优化的,但我会在几台旧PC和一些移动设备上测试你的JS解决方案,然后将它折扣得太慢。

It looks like you are using absolute positioning. 看起来你正在使用绝对定位。 My informal tests show absolute layout to be significantly faster than float calculation. 我的非正式测试显示绝对布局明显快于浮点计算。 This makes sense if you think about the work that the browser must do to calculate a relatively sized and floated item, versus just drawing an element at a specific place with specific dimensions. 如果您考虑浏览器必须执行的工作来计算相对大小和浮动的项目,而不是仅仅在具有特定维度的特定位置绘制元素,这是有意义的。

If you wanted to really look at optimizing performance, you could only manipulate the content that was visible. 如果您想真正关注优化性能,则只能操作可见的内容。 This would be much more difficult than just resizing everything and would probably only be relevant if you had thousands of items on a page. 这比仅调整所有内容困难得多,如果页面上有数千个项目,则可能只会相关。

If you end up going the script route, you might want to take a look at jQuery Masonry for additional ideas. 如果您最终选择了脚本路径,您可能需要查看jQuery Masonry以获取其他想法。 I have heard good things about it and it gave me some good ideas for my own library. 我听说过它很好,它为我自己的图书馆提供了一些好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM