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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10548417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 10:13:31  来源:igfitidea点击:

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

javascripthtmlcss

提问by Christian Zeller

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.

我有多个具有固定宽度和高度的 div(想想某种带有文章图片的目录视图)。现在我想向它们展示类似于 float:left 的行为。这可确保浏览器窗口越大,一行中显示的 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. 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.

float:left 解决方案的缺点是,右侧有一个很大的白色间隙,直到另一个 div 适合。现在我的工作是将 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. The column and row count is dynamically calculated with JavaScript:

你可以看到,如果你调整浏览器窗口的大小,它的行为类似于 float:left,但空间在框之间均匀分布。列数和行数是用 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.

现在我想知道是否有没有 JavaScript 的解决方案?我更喜欢只使用 CSS 的解决方案,因为我可能在一页上有数百个 div。

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.

我查看了CSS3 Flexible Box Layout,但这似乎只对固定列布局有用。在我的示例中,列数是动态计算的。然后我尝试了CSS3 Multi-column Layout,我可以得到类似的工作,但 div 是垂直对齐的,在内部被切断,并且浏览器支持尚不存在。这似乎对文本更有用,但在我的情况下,我已经修复了带有图片的 div,它不应该被切断。

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

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

采纳答案by thirtydot

The closestpure 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 couldadd 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 fixfor 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 修复,在隐形盒子的想法出现之前。现在应该没有理由使用我的旧修复。)

回答by trapper

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/

回答by mplungjan

Perhaps MASONRYcan help with the placement?

也许MASONRY可以帮助安置?

回答by Tim Medora

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. Even abandoning IE 7 and 8 (which isn't practical) I couldn't find a pure CSS solution. I guess you could hack together a long list of media queries to accomplish this in a limited fashion.

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

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/. I've placed a couple hundred elements in the example.

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

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 muchmore 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 Masonryfor additional ideas. I have heard good things about it and it gave me some good ideas for my own library.

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