7

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

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

换句话说,我希望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 -------------------| |

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

4

3 回答 3

11

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

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

  1. w3 规范的旧版本
  2. 较旧的语法
  3. 或者他们只是还没有完全实施新的甚至旧的模型

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

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

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

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

这个flex-wrap属性是使多行魔术在大多数其他浏览器中发生的一个属性。预计Firefox在 22 版中全面支持新的 flexbox 模型,该模型计划于 2013 年 6 月 25 日发布 更新: Firefox 现在支持28 版以上的flex-wrap属性 /更新

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

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

编辑:正如@Cimmanon 在评论中指出的那样,要让它在他们需要支持的旧浏览器中工作,他们不需要支持box-lines: multiple。所以这不适用于旧版本的iOSSafariFirefox。我想这解释了为什么Firefox 20没有可以依赖的旧实现。由于 FlexieJS 不支持box-lines: multiple两者,因此它的源代码可能对尝试解决此问题没有太大帮助。编写自己的 JS 修复程序似乎是目前唯一解决方案。FlexieJS 的开发者一直在为新规范开发一个 polyfill. 这必须包含一些代码来修复旧浏览器中的多行。不过,目前似乎没有。如果你要写点什么,也许你可以联系他以获得一些见解。如果你让它工作,把你的代码传给他。如果你幸运的话,他已经完成了一些尚未出现在 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+ */
}
于 2013-04-21T13:08:13.900 回答
1

您可以通过两种方式执行此操作(如果您知道 .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/

于 2013-04-21T09:37:23.680 回答
1

这是 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 可以做到这一点。其他所有人都将获得回退体验。

于 2013-04-21T13:31:54.260 回答