CSS 具有单个容器和不同大小项目的 flexbox

CSS flexbox with single container and differently sized items

我正在尝试实现此定位概述的以下场景的弹性框

+----+----------+----+
|   1|2>        |  <3|
+----+----------+----+
|   4|5              |
|   v|v              |
+----+               |
     |               |
+----+------+--------+
|7>         |      <6|
+-----------+--------+

说明

问题

主要问题是所有项目都在同一个弹性容器中。因此,我在正确的位置将它们换行(换行)时遇到问题,即项目应该在项目 3 之后换行,而项目 2 和 3 必须延伸到整行,因此项目 3 可以完全在其右侧显示内容。

Here a working JSFiddle 初始 HTML 和 CSS 您可以继续工作。

一些想法

也许只是出于我的想法。通过使用 :before:after 并给它们正确的顺序,可以在 flexbox 容器中使用两个额外的项目。这样就可以模拟一些额外的内容以获得所需的结果。

如果有 flex 组会容易得多,因为可以将 flex-direction 更改为 column 并将多个项目 together:1&2&3、4&5 和 6&7 分组并将它们放置在 row 在具有适当宽度的 flex 组中。

我设法通过使用 flex-basis 获得了预期的结果。当第 1、2、3 和 4 项的基数均为 26% 时,第 4 项不再适合第一行。同样的事情可以应用于第二行。

然后可以将 flex-grow 应用于第 2、3、5、6 和 7 项以填充每行中剩余的 space。

最后 align-self 第 4 个项目,所以它没有使用与第 5 个项目相同的高度。

已更新 JSFiddle:http://jsfiddle.net/ojmghu3t/2/

更新: 当然你也可以用flex-basis指定px。但是这样就很难在正确的位置产生中断。

这是第 1 项和第 4 项具有固定值的 JSFiddle:http://jsfiddle.net/ojmghu3t/4/

实际上,你可以使用伪元素来实现:

main::before, main::after {
    content: '';        /* Enable pseudo-elements */
    margin-right: 100%; /* Force line break */
}
main::before {
    order: 4;           /* Place it before .i4 */
}
main::after {
    order: 5;           /* Place it after .i5 */
}

main {
  width: 200px;
  display: flex;
  flex-flow: row wrap;
  border: 1px solid #ccc;
  resize: horizontal;
  overflow: auto;
}
main::before, main::after {
  content: '';
  margin-right: 100%;
}
main::before {
  order: 4;
}
main::after {
  order: 5;
}
.i2, .i3, .i5, .i6, .i7 {
  flex-grow: 1;
}
.i5 {
  width: 0;
}
section {
  border: 1px solid #eee;
}
.i1, .i4 {
  width: 50px;
  text-align: right;
}
.i7 {
  text-align: right;
  order: 6;
}
.i1 { order: 1; }
.i2 { order: 2; }
.i3 { order: 3; }
.i4 { order: 4; }
.i5 { order: 5; }
.i6 { order: 7; }
.i7 { order: 6; }
<main>
  <section class="i1">1</section>
  <section class="i2">2</section>
  <section class="i3">3</section>
  <section class="i4">4</section>
  <section class="i5">This one has much more content than the rest.</section>
  <section class="i6">6</section>
  <section class="i7">7</section>
</main>

解决方案

我现在想出了这个解决方案,使用了 的一些想法,并意识到所有支持 flexbox 的浏览器也支持 calc CSS 功能。基于此,我能够使 flexbox 容器变得灵活,并使项目在我需要的点中断。

Jan 的回答解决了我的布局问题,假设所有项目宽度都相对于容器,但项目 #1 和 #3 具有固定宽度。其他的都根据布局灵活。

我只是添加了最重要的 CSS,它定义了灵活容器上的灵活项目宽度。我将 .itemX 称为弹性项目 X 的选择器,其中 X 是元素编号。所以这些选择器只是为了更容易理解的伪代码。相应调整:

.itemAll {
    flex-grow: 1;
}

.item1,
.item4 {
    flex-grow: 0;
    flex-basis: @FixedWidth; /* i.e. 25px */
}

.item2,
.item3 {
    flex-basis: calc((100% - @FixedWidth)/2);
}

.item5 {
    flex-basis: calc(100% - @FixedWidth);
}

.item6,
.item7 {
    flex-basis: 50%;
}

从我修改后的 JSFiddle example 可以看出,这确实有效。尝试调整结果面板的宽​​度,您会看到除 #1 和 #4 之外的所有弹性项目都根据容器调整宽度,并始终保持定义的布局。