【问题标题】:Fitting as many divs as possible horizontally in HTML, and filling the line width在 HTML 中水平放置尽可能多的 div,并填充线宽
【发布时间】:2014-05-13 22:17:42
【问题描述】:

我有一堆固定宽度的div 元素,使用inline-block 显示类型设计为内联流动。这会在行尾留下一个空白空间(下一个 div 无法安装并换行到下一行)。

我想做的是均匀地扩展行上的所有 div 以填满行,类似于文本的“对齐”对齐方式

换句话说,我想在div 元素上设置最小宽度,并在一行中尽可能多地容纳它们,并填满整行。

这是我的示例 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>

纯 CSS + HTML 可以吗?还是我必须写一个脚本才能达到这个结果?


更新:由于人们一直建议使用百分比宽度来容纳单行中的项目,我必须注意这不是这个问题的意图。我想要类似“Justified”文本,但带有块。项目的数量是可变的,并且可能太多。

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


更新 2:

当前示例产生如下内容:

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

我希望看到这样的东西:

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

或者这个:

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

每个项目都有一个最小尺寸,因此在上面的示例中,项目 #4 和 #7 将不适合行上的剩余空间,并将换行到下一行。我想要那些已经安装到生产线上的来填满空间。

请注意,容器可能会重新调整大小,因为浏览器可以重新调整大小。所以,如果它变小到只有两个项目可以排成一行,我希望看到这样的东西:

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

我希望这可以清除问题的意图。

【问题讨论】:

  • 使用 CSS,将 div 标签宽度设置为百分比。
  • 我已经试过了。它不会产生预期的结果。一行中div 元素的数量是可变的,并且会根据容器(浏览器窗口)的宽度而变化。
  • 我不知道这是否可行,但由于 inline-block 对 line-height、letter-spacing 和 text-align: center 有反应,也许你可以简单地使用 text-align: justify?跨度>

标签: html css


【解决方案1】:

您可以使用flexbox model 执行此操作,但存在一些问题。

有一个旧的和一个新的 flexbox 模型,这确实使事情变得有点复杂。目前只有Chrome and Opera支持新模型,其他浏览器有“部分支持”,表示可能支持:

  1. older version of the w3 specifications
  2. older syntax
  3. 或者他们只是还没有完全实施新模型甚至旧模型

利用今天可用的任何东西,我能够将适用于 Chrome 26Safari 5.1.7IE10、IE9 模式下的 IE10 和 IE8 模式下的 IE10。遗憾的是,我当前的 Firefox 版本 20 不在该列表中。我不确定它是否适用于旧版本的 Firefox(我在帖子底部附近的 jsFiddle 中添加了所需的 CSS,但我的 PC 上没有安装任何旧版本)。

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

Firefox (Gecko) - 不支持。 Firefox 仅支持单行 flexbox。

我对此不是 100% 确定,但在我看来,即使在旧版本中,他们也从未支持 flex-wrap 属性。如果我错了,请纠正我,对任何拥有 Firefox 19- 版本的人,但我认为如果他们有,Firefox 20 至少会依靠它只要他们还没有完全实现新的 flexbox 模型。

这个flex-wrap 属性是使多行魔法在大多数其他浏览器中发生的一个属性。 预测 Firefox 将是 fully supporting the new flexbox model in version 22,即 scheduled to be released on June 25, 2013 更新: Firefox now does support flex-wrap 属性 @987654329 @/UPDATE

毕竟,根据我最近的研究,这是一个jsFiddle,它可以尽可能地完成这项工作。在当前浏览器支持下,这似乎是您在纯 CSS + HTML 中可以做到的最好的事情。

如果你想要现在更好的东西,你必须想出一个 JS 解决方案。也许看看flexieJS 的来源并修改浏览器检测代码,使其也能处理Firefox 20box-packbox-orient 在 FlexieJS 支持的属性列表中,它们是使这项工作在较旧的 iOSSafari 上工作的属性。

编辑:正如@Cimmanon 在 cmets 中指出的那样,要使其在旧版浏览器中工作,他们需要支持 box-lines: multiple,但他们不支持。所以这不适用于旧版本的 iOSSafariFirefox。我想这解释了为什么 Firefox 20 没有可以依赖的旧实现。由于 FlexieJS 也不支持box-lines: multiple,因此它的源代码可能对尝试解决此问题没有太大帮助。编写自己的 JS 修复程序似乎是现在唯一的解决方案。 FlexieJS 的开发者一直致力于polyfill for the new specification。这必须包含一些代码来修复旧浏览器中的多行。不过,目前似乎没有。如果你要写点什么,也许你可以联系他以获得一些见解。如果你让它工作,把你的代码传给他。如果你幸运的话,他已经完成了一些尚未在 GitHub 上发布的内容。

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+ */
}

【讨论】:

  • 这里有很多“信息”可以让您的答案看起来令人印象深刻,但它并未反映在您提供的 CSS 中。因为没有浏览器实现 box-lines: multiple(包装在 2009 规范中所必需的),它最终会在您为其提供前缀/属性的浏览器中被破坏。
  • 感谢或提供信息,我想它解释了为什么 Firefox 20 没有可依赖的旧实现。
  • 感谢您提供详细信息。 IE10 的行为完全符合我的预期,这很酷。但我最终决定暂时不使用这种尖端的规范,因为我的最终用户不是那么最新!但是了解这种“flexbox 模型”是件好事。
【解决方案2】:

您可以通过两种方式做到这一点(如果您知道 .items 有多少):

示例一: 浮动 .items 工作,见小提琴http://jsfiddle.net/David_Knowles/wh5bP/

#container { 
    margin: 100px; 
    overflow:hidden;
    border: 1px solid blue; 
}
.item { 
    width: 23%; /* important: (100% / numberOfItems - margin%) */
    margin: 0 1%; /* important */
    float:left; /* important */
    -moz-box-sizing: border-box; /* only needed to compensate for the border used in your debugging */
    -webkit-box-sizing: border-box; 
    box-sizing: border-box;
    border: 1px solid red; 

}

示例二:

行内块元素对换行符之间的空白很敏感。注意 .items 之间没有空格。 http://jsfiddle.net/David_Knowles/wh5bP/1/

<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>

.item { 
    width: 23%;
    margin: 0 1%;
    display:inline-block;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box; 
    box-sizing: border-box;
    border: 1px solid red; 

}

如果您永远不知道会有多少 .items,那么您可以看看 flexbox 模型。 http://css-tricks.com/using-flexbox/ http://caniuse.com/flexbox

如果您的目标受众使用 IE9 或更低版本,那么您还需要使用 polyfill。 http://flexiejs.com/

【讨论】:

  • 那么物品的最小尺寸在哪里?我知道如何使用百分比大小。这不是我要找的。请更仔细地阅读问题。我希望每个项目都有一个最小尺寸,如果它们不适合一行,则换行。
  • 我不明白你所说的“换行到下一行”是什么意思。什么应该换行到下一行;里面的文字还是.item?那个包裹的物品现在应该有多宽?视觉草图可能会有所帮助或您自己的小提琴。
  • 是的,这解释了很多 :-) 你需要纠正一些 JS 来确定解决这个问题。我很想看看你的想法。
  • 如果您将 Flexbox 用作解决方案,永远不要单独使用旧的 Flexbox 属性。
  • 感谢您的信息和努力。您的帖子是正确的,并且包含了很好的指导,这对我很有帮助,但我将 user1846192 的答案标记为已接受,因为它为未来的读者提供了更详细的信息和比较。
【解决方案3】:

这是 Flexbox 的工作,但您必须决定如何为非 Flexbox 浏览器布局。将事物与中心对齐可能是您最好的选择。

http://codepen.io/cimmanon/pen/lBDwu

ul {
  display: -webkit-flexbox;
  display: -ms-flexbox;
  display: -webkit-flex;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  list-style: none;
  padding: 0;
  text-align: center;
  /*  text-align: justify;
    -moz-text-align-last: justify;
    text-align-last: justify;*/
}
@supports (flex-wrap: wrap) {
  ul {
    display: flex;
  }
}

li {
  display: inline-block;
  -webkit-flex: 1 0;
  -ms-flex: 1 0;
  flex: 1 0;
  min-width: 10em;
  background: #CCC;
  border: 1px solid;
  margin: .5em;
}

由于需要换行,只有 Chrome、Opera 和 IE10 可以做到这一点。其他所有人都将获得回退体验。

【讨论】:

  • 感谢您的信息和努力。您的帖子是正确的,并且包含了很好的指导,这对我很有帮助,但我将 user1846192 的答案标记为已接受,因为它为未来的读者提供了更详细的信息和比较。
  • 即使 user1846192 有错误的解决方案并且在一半的浏览器中都被破坏了,他们还是仅仅因为它有很多其他信息让它看起来令人印象深刻而被接受?这对未来的读者有什么帮助?您的问题不是关于 Flexbox 本身的技术问题,选择损坏的解决方案而不是正确的解决方案似乎不太公平。
猜你喜欢
  • 2018-01-13
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
  • 2014-02-20
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
相关资源
最近更新 更多