html - 在仅使用 CSS 的 flex 布局的行/列中,让某些元素沿交叉轴堆叠

标签 html css flexbox

有一次我曾考虑过 CSS 规范的建议,但后来我想可能已经有一个我缺少的解决方案了。我正在谈论的那种布局的示例如下所示:

+-----------+---+
|     1     | 6 |
+---+---+---+   |
| 2 | 3 | 4 +---+
+---+---+---+ 7 |
|     5     |   |
+-----------+---+

问题是左列中间的那三个框沿交叉轴堆叠,我无法在 CSS 中找到执行此操作的机制。我知道这可以通过将 div 包裹在行方向 flex 布局的这 3 个元素上来完成,但是这种方法破坏了 flex 布局的灵 active ,因为这些元素不能再围绕外部布局和列/换行不能再发生在它们之间。那么,如何仅使用 CSS 来实现这一点,从而使 flex 布局保持灵活?

HTML:

<div id="flex-layout">
<div id="item1">1</div>
<div id="item2">2</div>
<div id="item3">3</div>
<div id="item4">4</div>
<div id="item5">5</div>
<div id="item6">6</div>
<div id="item7">7</div>
</div>

CSS:

#flex-layout {
    display: flex;
    flex-direction: column;
    height: 300px;
    width: 400px;
    flex-wrap: wrap;
    align-items: stretch;
}

#item1 {
    flex: 0 0 100px;
    width: 300px;
}

#item2 {
    flex: 0 0 100px;
    width: 100px;
}

#item3 {
    flex: 0 0 100px;
    width: 100px;
}

#item4 {
    flex: 0 0 100px;
    width: 100px;
}

#item5 {
    flex: 0 0 100px;
}

#item6 {
    flex: 0 0 150px;
    width: 100px;
}

#item7 {
    flex: 0 0 150px;
}

最佳答案

使用多个 flex 容器会更容易。

但是如果你想要一个单一的容器,你仍然可以做到,但前提是:

  • 已知6和7的宽度
  • 已知2、3、4的高度

然后,你可以

  • 使用行布局

    ┌─┬─┬─┬─┬─┬─┬─┐
    │1│2│3│4│5│6│7│
    └─┴─┴─┴─┴─┴─┴─┘
    
  • 重新排序 flex 元素:1,6,2,3,4,5,7

    ┌─┬─┬─┬─┬─┬─┬─┐
    │1│6│2│3│4│5│7│
    └─┴─┴─┴─┴─┴─┴─┘
    
  • 允许使用 flex-wrap: wrap 换行。

  • 使用伪元素在2之前和4之后强制换行

    ┌─┬─┐
    │1│6│
    ├─┼─┼─┐
    │2│3│4│
    ├─┼─┼─┘
    │5│7│
    └─┴─┘
    
  • 在 6 和 7 上使用 flex-grow: 0。在其他的上使用 flex-grow: 1

    ┌─────────┬─┐
    │    1    │6│
    ├───┬───┬─┴─┤
    │ 2 │ 3 │ 4 │
    ├───┴───┴─┬─┤
    │    5    │7│
    └─────────┴─┘
    
  • 设置所需的with,w,为6和7。添加margin-right: w为4

    ┌─────┬───┐
    │  1  │ 6 │
    ├─┬─┬─┼───┘
    │2│3│4│
    ├─┴─┴─┼───┐
    │  5  │ 7 │
    └─────┴───┘
    
  • 将所需的高度 h 设置为 2、3 和 4。将 margin-bottom: -h/2 添加到 6,并将 margin-top: -h/2 到 7.

    ┌─────┬───┐
    │  1  │ 6 │
    ├─┬─┬─┤   │
    │2│3│4├───┤
    ├─┴─┴─┤ 7 │
    │  5  │   │
    └─────┴───┘
    
  • 此外,向 2,3,4 添加 widthmax-width 可能是个好主意。否则,如果它们的内容足够宽,它们将被放在不同的行中,破坏布局。

代码如下:

#flex-layout {
  display: flex; /* Magic begins */
  flex-wrap: wrap; /* Multiline */
}
#item1 { order: 1; }
#item6 { order: 2; }
#item2 { order: 3; }
#item3 { order: 4; }
#item4 { order: 5; }
#item5 { order: 6; }
#item7 { order: 7; }
#flex-layout > div {
  border: 1px solid;
  box-sizing: border-box;
}
#item2, #item3, #item4 {
  height: 50px; /* h */
}
#item6 {
  margin-bottom: -25px; /* -h/2 */
}
#item7 {
  margin-top: -25px; /* -h/2 */
}
#item1, #item2, #item3, #item4, #item5 {
  flex-grow: 1;
}
#item6, #item7 {
  width: 25%; /* w */
  flex-grow: 0;
}
#item4 {
  margin-right: 25%; /* w */
}
#flex-layout:before {
  /* Force line break before #item2 */
  content: '';
  width: 100%;
  order: 3;
}
#flex-layout:after {
  /* Force line break after #item4 */
  content: '';
  width: 100%;
  order: 5;
}
<div id="flex-layout">
  <div id="item1">1</div>
  <div id="item2">2</div>
  <div id="item3">3</div>
  <div id="item4">4</div>
  <div id="item5">5</div>
  <div id="item6">6</div>
  <div id="item7">7</div>
</div>

关于html - 在仅使用 CSS 的 flex 布局的行/列中,让某些元素沿交叉轴堆叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30489151/

相关文章:

Flexbox 中的 HTML5 视频高度错误

javascript - 页脚链接在移动 View 中消失

html - DOCTYPE RSS 和 HTML 实体

css - 媒体查询中的 "screen"和 "only screen"有什么区别?

javascript - 使图像轮播响应

html - CSS 标题以背景为中心,与文本一样长

css - 强制高度未知的 Flexbox 元素上边距

css - Flexbox:等高行?

javascript - 使 div 滚动直到到达页面顶部然后固定

javascript - 分配唯一的 ID 和名称?