如何进行显示:flex容器水平展开并包裹内容?

时间:2014-05-01 13:20:16

标签: html css flexbox

使用css flexbox时,三个主要浏览器在某些区域的行为似乎完全不同。

在这种情况下,我正在尝试创建一个图像网格:

<div class="container">
     <div class="photo"></div>
     <div class="photo"></div>
     <div class="photo"></div>
     <div class="photo"></div>
     <div class="photo"></div>
     <div class="photo"></div>
</div>


.container {
    display:inline-flex;
    flex-flow : column wrap;
    align-content : flex-start;
    height : 100%;
}

在这个例子中,我需要一个容器,它本身包含几个div元素,这些元素设置为从顶部到底部流动,并在它们到达底部时进行包装。最终为我提供了一系列照片。

但是我需要容器水平扩展以容纳包裹的元素:

这是一个快速jsFiddle来演示。

行为如下:

  • IE 11 - 正确,容器水平拉伸以包裹每列包裹的元素
  • Firefox - 容器只包装第一列元素,其余元素溢出。
  • Chrome - 容器始终会拉伸以填充其父级的宽度,无论可能是什么。

在这个例子中,我想在其他两个浏览器中实现IE11的行为。因此,我的问题是,如何使flexbox容器水平扩展以匹配其column wrap内容。

提前致谢。

5 个答案:

答案 0 :(得分:29)

很奇怪大多数浏览器都没有正确实现列弹性容器,但对写入模式的支持相当不错。

因此,您可以使用具有垂直书写模式的行flex容器。这将使块方向与内联方向交换,因此flex项将垂直流动。然后,您只需要恢复弹性项目内的水平书写模式。

.container {
  display: inline-flex;
  writing-mode: vertical-lr;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 350px;
  background: blue;
}
.photo {
  writing-mode: horizontal-tb;
  width: 150px;
  height: 100px;
  background: red;
  margin: 2px;
}
<div class="container">
  <div class="photo">1</div>
  <div class="photo">2</div>
  <div class="photo">3</div>
  <div class="photo">4</div>
  <div class="photo">5</div>
  <div class="photo">6</div>
  <div class="photo">7</div>
  <div class="photo">8</div>
  <div class="photo">9</div>
</div>

这种方法在边缘情况下可能有自己的错误,特别是如果您混合高级布局技术(如浮点数和嵌套的Flexbox)。但对于大多数情况,它似乎正常工作。

答案 1 :(得分:7)

似乎这个问题不能只用CSS来解决,所以我建议你使用JQuery解决方案

容器宽度=最后一个孩子的位置 - 容器的位置+最后一个孩子的宽度(包括边距)

代码:

$(document).ready(function() {
 $('.container').each(function( index ) {
     var lastChild = $(this).children().last();
     var newWidth = lastChild.position().left - $(this).position().left + lastChild.outerWidth(true);
     $(this).width(newWidth);
    })
});

演示:

http://jsfiddle.net/qzea320L/

答案 2 :(得分:7)

规范说你正在做的事情应该有效,但除了Internet Explorer / Edge之外,它在每个主要浏览器中都被错误地实现,使得大多数开发人员目前无法使用多行inline-flex column布局。这是Chromium bug report提供的示例与您的实际有效,并注意到它在Chrome,Safari和Firefox中呈现错误。

规范中的论点比我能理解的更复杂,但关键是Flexible Box Layout Module Level 1规范定义了灵活容器的内在交叉大小(即,Flex Container Intrinsic Cross Size部分中flex-direction: row弹性容器的固有高度或flex-direction: column弹性容器的固有宽度)。在那里,陈述:

  

对于multi-line flex containermin-content / max-content cross size是弹性线交叉尺寸的总和

也就是说,flex-direction: column flex容器的固有宽度应该是其列宽度的总和,正如您所期望的那样。 (比这更复杂,我不明白这一点,但我相信上述内容大致正确。)但是,Chrome,Firefox和Safari都错误地计算了这个宽度;在Chrome中的width: min-content width: max-content框中设置column wrapflex,您可以清楚地看到宽度设置为最宽的单个元素的宽度。

存在silly Chrome-specific workaround,但最好避免使用。在修复错误之前,Flexbox模型的这一部分根本无法按设计工作,并且没有可用的干净解决方案。

答案 3 :(得分:-1)

您有一个具有固定高度容器的列布局分布。

将flex-direction设置为column时,将Vertical轴定义为主轴。

在flexbox中,这意味着它将填满可用高度,然后创建一个新列。

在此 JSBIN 中,我使用javascript更改容器的高度,因此,您将看到子项目移动。

PS:你不应该依赖IE行为,因为他们的弹性支持是最近的。

答案 4 :(得分:-1)

另一种可能的方法:

.container {
  column-count: 2; /*or whatever */
}
.container > div {
  display: inline-block;
}

https://developer.mozilla.org/en-US/docs/Web/CSS/column-count

如果margin-top中的.container > div:first-child与顶部不对齐,您可能还需要调整它们。