在主容器自身换行之前,使嵌套的 flex 容器中的项目换行。

23

如果我有一个包含多个容器的弹性盒子容器,我如何使这些容器中所包含的项目在容器本身之前换行?

例如(codepen):

HTML:

<div>
    <row>
        <column id="first">
            <widget width=1 height=8></widget>
            <widget width=1 height=8></widget>
        </column>
        <row id="second">
            <widget></widget>
            <widget></widget>
            <widget></widget>
        </row>
    </row>
</div>

CSS

column, row, widget {
  background: RGBA(0,0,0,.2);
  margin: 1em;
  display: flex;
  flex-wrap: wrap;
  align-items: top;
  align-content: flex-start;
}

row {
  flex-direction: row;
}

column {
  flex-direction: column;
}

widget {
  min-height: 100px;
  flex-grow: 2;
  flex-shrink: 1;
  width: calc(25% - 3em);
  min-width: 300px;
  height: 100px;
  flex-basis: 0;
  padding: .5em;
  display: block;
}

widget[width=1] {
  flex-grow: 1;
  min-width: 150px;
}

widget[width=4] {
  flex-grow: 4;
  min-width: 600px;
}

widget[width=8] {
  flex-grow: 8;
  min-width: 1200px;
}

widget[height=1] {
  min-height: 150px;
}

widget[height=4] {
  min-height: 600px;
}

widget[height=8] {
  min-height: 1200px;
}

widget {
  background: RGBA(200,0,20,.5);
}
我希望在 #first 下方换行之前先换行 #second 中的项目。换句话说,我总是想首先尝试内层项目的换行,然后再尝试外层项目的换行,这似乎与默认情况相反。有没有什么方法可以做到这一点?

编辑: 有人要求进行视觉澄清。

两个容器,每个容器都有几个项目: full width

期望的行为稍小。内部项目在它们的容器之前换行。

partially wrapped

期望的行为更小。

inner items fully wrapped

期望的行为最小。当内部项目无法再次换行时,容器最终才会换行。

containers wrapped

实际发生的情况是,容器在其内容之前换行。

enter image description here

enter image description here


1
我不理解所需的行为。你能添加一张图片或其他吗? - Oriol
1个回答

4
我不认为有任何flex属性可以使这个过程变得简单易行。然而,flexbox规范确实允许绝对定位的flex子元素。因此,在媒体查询和绝对定位的组合下,容器中的flex项可以在容器本身换行之前被换行。
请尝试以下操作: HTML(无更改) CSS(添加媒体查询和绝对定位)
#second { position: relative; } 
/* establishes nearest positioned ancestor for absolute positioning */

@media screen and (max-width: 1000px) { 
    #second widget:nth-child(3) { 
        position: absolute; 
        left: 0; 
        bottom: 0; 
        width: 90%; }
    }

@media screen and (max-width: 800px) {  
    #second { height: 375px; }
    #second widget:nth-child(2) { 
        position: absolute; 
        left: 0; 
        bottom: 127px; 
        width: 75%; }
    #second widget:nth-child(3) { 
        position: absolute; 
        left: 0; 
        bottom: 0; 
        width: 75%; }   
    }

/* final media query removes absolute positioning and restores flex properties */       
@media screen and (max-width: 600px) {  
    column, row, widget { flex-wrap: wrap; }
    #second widget {
        position: static;
        width: calc(25% - 3em);
        min-width: 300px;
    }

Codepen已更新

请注意,尽管这段代码可以实现问题所要求的功能 - 即在容器自身包裹之前将flex项目包裹起来,但它只是用来传达解决方案基本概念的。问题,例如flex项目的边距和宽度,我认为超出了此问题的范围,可能仍需要解决。


谢谢!难道没有不预先知道项目(小部件)宽度的方法来完成这个吗? - whereswalden
我所使用的宽度是基于你代码中的宽度。然而,如果你移除了宽度,那么盒子的宽度将只会足够包裹内容。就像我在回答末尾提到的,这个解决方案是实现你想要的一个方法,但是 -- 我不知道你的具体内容 -- 你可能需要做出一些调整(可能使用 min-widthmax-widthoverflow 属性),以使其运行顺畅。 - Michael Benjamin
但是每次我从页面中添加/删除项目时,我都需要修改CSS,对吧?这基本上只是硬编码了首选的换行行为,而不是通用的? - whereswalden
小部件需要放在容器中吗?如果您删除 #second,并将小部件作为 row 的子项,则可以放弃所有此代码。否则,对于您的两个问题是肯定的,因为没有 CSS 属性会强制 flex 项目在其容器之前换行,解决方法代码可能会有点混乱。您可能需要考虑使用 JavaScript 作为替代方案。 - Michael Benjamin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接