根据可用的 space,在一个全角大 div 上方和下方放置一组小 div

Place a set of small divs above and below one full-width large div depending on space available

假设我有一个由任意数量的小 div 和一个大 div 组成的布局。我想要一排小 divs,尽可能多地容纳容器宽度,然后是大 div,占据整个宽度。它还将在高度上弯曲,保持其纵横比(包含图像)。任何剩余的小 divs 然后在大的之后继续。随着容器的膨胀和收缩,小的 div 会在 space 允许的情况下移动 below/above 大的。希望只有 CSS 的解决方案(尽管对 JS 开放)。

所以最初:

---------------------
| d1 | d2 | d3 | d4 |
---------------------
|         DB        |
---------------------
| d5 | d6 | d7 | d8 |
---------------------

然后容器收缩,造成这样的布局:

----------------
| d1 | d2 | d3 |
----------------
|      DB      |
----------------
| d4 | d5 | d6 | 
----------------
| d7 | d8 |

我正在设想一个 flexbox 解决方案,但未能实现。

Mavbe 你可以尝试使用 css 网格和 grid-area

.parent {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  justify-items: center;
}

.div5 { grid-area: 2 / 1 / 3 / 5; }


@media (max-width: 400px) {
  .parent {
    grid-template-columns: repeat(3, 1fr);
  }

  .div5 { grid-area: 2 / 1 / 3 / 4; } 
}
<div class="parent">
  <div class="div1">1</div>
  <div class="div2">2</div>
  <div class="div3">3</div>
  <div class="div4">4</div>
  <div class="div5">DB</div>
  <div class="div6">5</div>
  <div class="div7">6</div>
  <div class="div8">7</div>
  <div class="div9">8</div>
</div>

如果小divs可以一样大,CSS格 可以工作。

Flexbox 在这里不起作用,因为它不允许你定义这种“第一行尽可能多地填充项目,然后放置一个大项目,然后继续”的逻辑。在 Flexbox 中,您必须定义项目放置在弹性行中的顺序。

CSS Grid让您更随意地放置网格项目。所以你可以确保你的大 div 总是横跨所有列,并且它被放在第二行。而所有的小 div 将填满剩余的 space.

不过有一点需要注意。如果您要使用 CSS 网格创建“适合该屏幕大小的尽可能多的列”,则不能根据内容调整小 div 的大小。

这是一个可行的解决方案示例。每个小 div 的每一列至少 200px 宽,如果水平方向有任何剩余空闲 space,它会增长一点。显然你可以为每个小 div.

选择你自己的最小尺寸

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

div {
  padding: 24px;
  text-align: center;
  border: 1px solid black;
}

div:nth-of-type(odd) {
  background-color: whitesmoke;
}

.big-div {
  grid-row: 2;
  grid-column: 1 / -1;
}
<main class="grid-container">
  <div>Small</div>
  <div>Small</div>
  <div>Small</div>
  <div class="big-div">Big</div>
  <div>Small</div>
  <div>Small</div>
  <div>Small</div>
  <div>Small</div>
  <div>Small</div>
</main>

如果 divs 的高度已知,您可以使用 flexbox 的技巧。

在第一个小 div 上设置保证金以在第二行创建 space,将大移动到此 space

悬停代码段以查看它是否有效

.container {
  display: flex;
  width: 200px;
  border: solid 1px black;
  position: relative;
  flex-wrap: wrap;
  transition: linear 5s;
}

html:hover .container {
    width: 900px;
}

div {
  width: 150px;
  height: 50px;
  flex-shrink: 0;
  flex-grow: 0;
  margin: 4px;
  background-color: lightgreen;
}

#first {
   margin-bottom: 60px;  /* big height */
}

div.big {
  width: 100%;
  height: 50px;
  background-color: lightblue;
  position: relative;
  position: absolute;
  transform: translate(0px, 55px);   /* small height */
}
<main class="container">
  <div class="big">Big</div>
  <div id="first">1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
</main>