在HTML中水平填充尽可能多的div,并填充行宽 [英] Fitting as many divs as possible horizontally in HTML, and filling the line width

查看:972
本文介绍了在HTML中水平填充尽可能多的div,并填充行宽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆固定宽度的 div 元素,使用 inline-block 显示类型以内联方式流动。这在行尾留下了一个空白空间(下一行 div 无法装入并包装到下一行)。

我想要做的是平均扩展该行中的所有div以填充行,类似于文本的对齐对齐



换句话说,我希望在 div 元素上具有最小宽度,并尽可能多地适合元素



这是我的示例HTML: c $ c><!DOCTYPE html PUBLIC - // W3C // DTD XHTML 1.0 Transitional // ENhttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
< html>
< head>
< style>
#container {margin:100px;填充:10px;边框:1px纯蓝色; }
.item {margin:10px;宽度:300px; min-width:300px;显示:inline-block;边框:1px纯红色; }
< / style>
< / head>
< body>
< div id =container>
< div class =item>第一项< / div>
< div class =item>第二项< / div>
< div class =item>第三项< / div>
< div class =item>第四项< / div>
< / div>
< / body>
< / html>

纯CSS + HTML可以实现吗?或者我必须编写一个脚本来实现这个结果?






更新:由于人们不断建议使用百分比宽度来在一行中合适的项目,我必须指出,这不是这个问题的意图。我想拥有合理的文字,但有块。项目数量是可变的,可能太多。

块的大小必须相同,并且有一个默认(最小)宽度,如果需要,它们可以将它们换到下一行,并且需要容器的宽度通过扩展它们的宽度来填充子项目。




更新2:



当前样本产生如下所示:

  | -------------- -------------容器----------------------------- | 
| | ------ 1 ------ | | ------ 2 ------ | | ------ 3 ------ | |
| | ------ 4 ------ | | ------ 5 ------ | | ------ 6 ------ | |
| | ------ 7 ------ | |

我期待看到类似这样的内容:

  | ----------------------------容器------- --------------------- | 
| | -------- 1 -------- | | -------- 2 -------- | | -------- 3 -------- | |
| | -------- 4 -------- | | -------- 5 -------- | | -------- 6 -------- | |
| | -------- 7 -------- | |

或者:

  | ----------------------------容器-------------- -------------- | 
| | -------- 1 -------- | | -------- 2 -------- | | -------- 3 -------- | |
| | -------- 4 -------- | | -------- 5 -------- | | -------- 6 -------- | |
| | ------------------------------ 7 ------------------ ------------ | |

每个项目都有一个最小尺寸,所以在上面的例子中,项目#4和#7不会适合线上的剩余空间并将换行到下一行。我希望那些已经安装到该行的空间填满空间。



请注意,容器可能会重新调整大小,因为浏览器可能会重新调整大小。所以,如果它变得更小,只有两个项目适合连续,我想看到这样的事情:

  | -----------------容器----------------- | 
| | -------- 1 -------- | | -------- 2 -------- | |
| | -------- 3 -------- | | -------- 4 -------- | |
| | -------- 5 -------- | | -------- 6 -------- | |
| | ------------------- 7 ------------------- | |

我希望这可以解决问题的意图。

解决方案

您可以使用 flexbox模型,但仍然存在一些问题。



有一个旧的和新的flexbox模型,这确实使事情变得复杂。目前只有 Chrome和Opera 支持新模式,其他浏览器具有部分支持,这意味着他们可能会支持:


  1. w3规范的旧版本 旧语法 旧模型

无论今天有什么可用,我都能够将 Chrome 26 Safari 5.1.7 IE10 模式下的 IE10 。可悲的是,我目前的 Firefox版本20 不在该列表中。我不确定它是否可以在老版本的Firefox中工作(我已经在帖子底部附近的jsFiddle中添加了所需的CSS,但是我的电脑上没有安装任何旧版本)。



链接解释了为什么它在 Firefox 20 中不起作用。如果您向下滚动到页面底部,则会指出 flex-wrap 属性:


Firefox(Gecko) - 不支持。 Firefox仅支持单线Flexbox。

我对此并不十分确定,但在我看来,他们从来没有即使在旧版本中也支持 flex-wrap 属性。如果我错了,请将我改正为使用 Firefox 19 - 版本的任何人,但我认为,如果他们有, Firefox 20 至少会回退到只要他们还没有完全实施新的Flexbox模型。



这个 flex-wrap 属性是这使得多线魔法在大多数其他浏览器中都会发生。 预计 Firefox 将会完全支持版本22中的新Flexbox模型 a>,这是计划于2013年6月25日发布 更新: Firefox现在支持 flex-wrap 属性版本28以上。 / UPDATE



毕竟,这里有一个。这似乎是目前浏览器支持的最好的纯CSS + HTML格式。



如果您现在想要更好的 ,你将不得不想出一个JS解决方案。也许看看 flexieJS 的来源并修改浏览器检测代码,以便它能处理 Firefox 20 box-pack box-orient 位于FlexieJS支持的属性列表中,它们是正在制作的属性此工作适用于旧版 iOS Safari

编辑:正如@Cimmanon在评论中指出的,为了让它在旧版浏览器中运行,他们需要支持 box-lines:多个,他们没有。因此,这不适用于旧版 iOS Safari Firefox 。我想这解释了为什么 Firefox 20 没有旧的实现可以重新使用。由于FlexieJS不支持 box-lines:multiple ,它的源代码可能不会对尝试解决这个问题有很大的帮助。编写自己的JS修补程序似乎是唯一的现在解决方案。 FlexieJS的开发人员一直在为新规范开发 polyfill 。这将不得不包括一些代码来修复旧版浏览器中的多行。目前看起来并不像现在。如果你要写点什么,也许你可以联系他获得一些见解。如果你得到它的工作,将他的代码传给他。如果你幸运的话,他已经有了一些东西已经不在GitHub上了。

CSS:

  #container {
margin:100px;
padding:10px;
border:1px纯蓝色;
display:-webkit-box; / * iOS 6-,Safari 3.1-6 * /
显示:-moz-box; / * Firefox 19- * /
display:-ms-flexbox; / * IE 10 * /
display:-webkit-flex; / * Chrome * /
display:flex; / * Opera 12.1,Firefox 20+ * /

/ * iOS 6-,Safari 3.1-6 * /
-webkit-box-orient:horizo​​ntal;
-webkit-box-pack:justify;
-webkit-lines:multiple; / *只有在这里为了提供信息的目的,这条线应该是它的工作原理,它从来没有实现* /

/ * Firefox 19- * /
-moz-flex-flow :换行;
-moz-justify-content:space-between;
-moz-box-lines:multiple; / *仅在这里提供信息的目的,这条线应该是它的工作原理,它从未实现过* /

/ * Chrome * /
-webkit-flex-flow:row包;
-webkit-justify-content:space-between;

/ * IE10 * /
-ms-flex-flow:换行;
-ms-justify-content:space-between;

/ * Opera 12.1,Firefox 20+ * /
flex-flow:换行;
justify-content:space-between;
}
.item {
margin:10px;
width:300px;
border:1px纯红色;
-webkit-box-flex:auto; / * iOS 6-,Safari 3.1-6 * /
-moz-box-flex:1.0; / * Firefox 19- * /
-webkit-flex:auto; / * Chrome * /
-ms-flex:auto; / * IE10 * /
flex:auto; / * Opera 12.1,Firefox 20+ * /
}


I have a bunch of fixed-width div elements styled to flow inline using inline-block display type. This leaves an empty space at the end of the line (where the next div could not be fitted and wrapped to the next line).

What I'd like to do, is to expand all of the divs on the row evenly to fill up the row, similar to the "Justify" alignment for the text.

In other words, I want to have a minimum width on div elements and fit as many of them as possible in a single row, and fill the entire row.

Here's my sample HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <style>
        #container { margin: 100px; padding: 10px; border: 1px solid blue; }
        .item { margin: 10px; width: 300px; min-width: 300px; display: inline-block; border: 1px solid red; }
    </style>
</head>
<body>
    <div id="container">
        <div class="item">Item One</div>
        <div class="item">Item Two</div>
        <div class="item">Item Three</div>
        <div class="item">Item Four</div>
    </div>
</body>
</html>

Is that possible with pure CSS + HTML? Or do I have to write a script to achieve this result?


UPDATE: Since people keep suggesting to use percentage widths to fit items in a single row, I have to note that it's NOT the intention of this question. I want to have something like "Justified" text, but with blocks. Number of items are variable, and can be too many.

The blocks need to be the same size, have a default (minimum) width that will cause them to wrap to next line if needed, and the container's width is needed to be filled with child items by extending their width.


UPDATE 2:

Current sample produces something like this:

|--------------------------- Container -----------------------------|
| |------ 1 ------| |------ 2 ------| |------ 3 ------|             |
| |------ 4 ------| |------ 5 ------| |------ 6 ------|             |
| |------ 7 ------|                                                 |

I'm looking to see something like this:

|---------------------------- Container ----------------------------|
| |-------- 1 --------| |-------- 2 --------| |-------- 3 --------| |
| |-------- 4 --------| |-------- 5 --------| |-------- 6 --------| |
| |-------- 7 --------|                                             |

Or this:

|---------------------------- Container ----------------------------|
| |-------- 1 --------| |-------- 2 --------| |-------- 3 --------| |
| |-------- 4 --------| |-------- 5 --------| |-------- 6 --------| |
| |------------------------------ 7 ------------------------------| |

Each item has a minimum size, so in the above example item #4 and #7 won't fit the remaining space on the line and would wrap to the next line. I want the ones already fitted to the line to fill up the space.

Note that the container may re-size because the browser can be re-sized. So, if it becomes smaller to the extent that only two items fit in a row, I'd want to see something like this:

|----------------- Container -----------------|
| |-------- 1 --------| |-------- 2 --------| |
| |-------- 3 --------| |-------- 4 --------| |
| |-------- 5 --------| |-------- 6 --------| |
| |------------------- 7 -------------------| |

I hope this clears the intent of the question.

解决方案

You can do this with the flexbox model, there are some issues though.

There is an old and a new flexbox model, which does make things kind of complicated. Currently only Chrome and Opera support the new model, and other browsers have "Partial support", which means that they might be supporting:

  1. An older version of the w3 specifications
  2. An older syntax
  3. Or they just haven't gotten around to fully implementing the new or even the old model yet

With whatever is available today I was able to put something together which works in Chrome 26, Safari 5.1.7, IE10, IE10 in IE9 mode and IE10 in IE8 mode. Sadly, my current Firefox version 20 is not in that list. I am not sure about if it will work in older versions of Firefox (I have added the required CSS in the jsFiddle near the bottom of the post, but I don't have any older versions installed on my PC).

This link explains why it does not work in Firefox 20. If you scroll down to the bottom of the page, it states about the flex-wrap property:

Firefox (Gecko) - Not Supported. Firefox supports only single-line flexbox.

I'm not 100% sure about this, but it seems to me that they have never supported the flex-wrap property even in older versions. Correct me if I'm wrong, to anyone with a Firefox 19- version out there, but I think if they had, Firefox 20 would at least fall back on it for as long as they have not yet fully implemented the new flexbox model.

This flex-wrap property is the one that makes the multi-line magic happen in most of the other browsers. The forecast is that Firefox will be fully supporting the new flexbox model in version 22, which is scheduled to be released on June 25, 2013. UPDATE: Firefox now does support the flex-wrap property from version 28 upwards. /UPDATE

After all that, here's a jsFiddle which does the job as well as possible, according to my recent research. This seems to be the best you can do in pure CSS + HTML with the current browser support.

If you want something better right now, you would have to come up with a JS solution. Maybe have a look at the source of flexieJS and modify the browser detection code so that it will handle Firefox 20 as well. box-pack and box-orient are on the list of supported properties of FlexieJS, they are the properties that are making this work on older iOS and Safari.

Edit: As @Cimmanon points out in the comments, to get this to work in older browsers they would need to support box-lines: multiple, which they don't. So this isn't going to work on older versions of iOS, Safari and Firefox. I guess this explains why Firefox 20 does not have an old implementation to fall back on. Since FlexieJS does not have support for box-lines: multiple either, its source is probably not going to be of much help with trying to fix this issue. Writing your own JS fix seems to be the only right now solution. The developer of FlexieJS has been working on a polyfill for the new specification. This would have to include some code to fix the multiline in older browsers. It does not look like there is any at the moment though. If you're going to write something, maybe you could contact him for some insights. Pass him your code if you get it working. If you are lucky he has got something going already which isn't up on GitHub yet.

The CSS:

#container {
  margin: 100px;
  padding: 10px;
  border: 1px solid blue;
  display: -webkit-box;     /* iOS 6-, Safari 3.1-6 */
  display: -moz-box;        /* Firefox 19- */
  display: -ms-flexbox;     /* IE 10 */
  display: -webkit-flex;    /* Chrome */
  display: flex;            /* Opera 12.1, Firefox 20+ */

  /* iOS 6-, Safari 3.1-6 */
  -webkit-box-orient: horizontal;
  -webkit-box-pack: justify;
  -webkit-lines: multiple;  /* Only here for informative purpose, this line is what should have made it work, it has never been implemented */ 

  /* Firefox 19- */
  -moz-flex-flow: row wrap;
  -moz-justify-content: space-between;
  -moz-box-lines: multiple; /* Only here for informative purpose, this line is what should have made it work, it has never been implemented */ 

  /* Chrome */
  -webkit-flex-flow: row wrap;
  -webkit-justify-content: space-between;

  /* IE10 */
  -ms-flex-flow: row wrap;
  -ms-justify-content: space-between;

  /* Opera 12.1, Firefox 20+ */
  flex-flow: row wrap;
  justify-content: space-between;
}
.item {
  margin: 10px;
  width: 300px;
  border: 1px solid red;
  -webkit-box-flex: auto;    /* iOS 6-, Safari 3.1-6 */
  -moz-box-flex: 1.0;        /* Firefox 19- */
  -webkit-flex: auto;        /* Chrome */
  -ms-flex: auto;            /* IE10 */
  flex: auto;                /* Opera 12.1, Firefox 20+ */
}

这篇关于在HTML中水平填充尽可能多的div,并填充行宽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆