【问题标题】:CSS flexbox with single container and differently sized items具有单个容器和不同大小项目的 CSS flexbox
【发布时间】:2015-02-20 15:55:23
【问题描述】:

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

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

说明

  • 上面的每个弹性项目都有它的订单号
  • 数字根据最终结果对齐(垂直和水平)
  • 只有编号的项目具有预定义的宽度
  • &lt;&gt;v 显示项目的维度灵活性,具体取决于它具有的内容量;
    • &gt; 内容将向右延伸
    • &lt; 内容将向左延伸
    • v 内容会向下延伸
  • 1 具有固定的宽度和高度
  • 1、2 和 3 的高度相同,但 2 和 3 的宽度可变
  • 4 和 5 已定义宽度但高度不同
  • 6 和 7 具有相同的高度但不同的宽度
  • 项目编号对应于它们在 HTML 中的位置
  • 请注意,与 HTML 相比,输出中的 6 和 7 是相反的

问题

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

Here a working JSFiddle 带有您可以处理的初始 HTML 和 CSS。

一些想法

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

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

【问题讨论】:

  • "主要问题是所有项目都在同一个弹性容器中。", "如果有弹性组会容易得多我>”。为什么你不能这样做?
  • @Oriol:因为根据项目类型,并非所有项目都以相同的顺序显示。将它们分组将无法在单个组之外订购。

标签: css flexbox


【解决方案1】:

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

然后flex-grow可以应用于项目2、3、5、6和7,以填充每一行的剩余空间。

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

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

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

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

【讨论】:

  • 好吧,只要 1 和 4 可以在整个宽度的百分比中任意调整大小,这似乎没问题。如果我希望它们具有以像素为单位的预定义大小并且在容器调整大小时它们应该保持其大小怎么办?
  • 当然,您也可以将px 用于某些元素(请参阅更新的答案)。对于固定宽度的容器,这不是问题。但是当容器没有固定宽度时,我看到在某些元素之后中断的唯一解决方案是使用媒体查询或 JavaScript。
【解决方案2】:

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

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>

【讨论】:

  • +1 这是一个非常好的技巧。只要你给伪元素整个宽度大小(你使用了一个不寻常的margin-right: 100%,但可以简单地设置它们的width:100% 来完成同样的事情)你就打破了界限。缺点是虽然这适用于两行和三行场景(涵盖我的布局),但在超过 3 行布局中失败。最终解决方案虽然适用于任何布局。但这是一个合理的想法。恭喜。
  • @RobertKoritnik True, width 也应该可以工作,但可能存在冲突,例如与max-width。如果您需要两个以上的换行符,您可以添加空元素而不是伪元素。不应出于样式目的更改标记,但它会起作用。
  • 是的,即使是伪元素也可以替换为空元素,尽管我不喜欢这个想法,因为为了正确显示某些内容,您需要一定的标记。所以你最终会得到一些标记,其中一些是为了造型而存在的。不是真正的语义......伪元素不是保持语义的标记源的一部分。
【解决方案3】:

解决方案

这个解决方案我现在想出了使用@Jan's answer 的一些想法,并意识到所有支持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 之外的所有 flex 项目都会根据容器调整它们的宽度,并始终保持它们的布局定义。

【讨论】:

    猜你喜欢
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    相关资源
    最近更新 更多