在同一容器中对齐具有不同高度的弹性项目

Align flex items with different heights in the same container

我想知道是否可以让弹性项目与同一容器中较大的弹性项目水平对齐。使用 CSS 浮动很容易完成,但我无法用 flex 项目完成它。

View this JSFiddle for a flexbox example.

View this JSFiddle a float example

网格布局

<div class="flex-container">
 <div class="large-flex-item">
</div>
<div class="small-flex-item">
 </div>
<div class="small-flex-item">
 </div>
</div>

CSS

 .flex-container {
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
   align-items: flex-start;
   max-width: 500px;
   margin-right: auto;
   margin-left: auto;
 }

 .small-flex-item {
   flex-basis: 33.333%;
   background: #000;
   padding-top: 30%;
 }

 .large-flex-item {
   flex-basis: 66.667%;
   background: #333;
   padding-top: 60%;
 }

可以通过嵌套flex容器实现布局

HTML

<div class="flex-container">

  <div class="large-flex-item"></div><!-- flex item #1 -->

  <div class="flex-container-inner"><!-- flex item #2 & nested flex container -->
     <div class="small-flex-item"></div><!-- this flex item and sibling will align... -->
     <div class="small-flex-item"></div><!-- ... in column next to .large-flex-item -->
  </div>

</div>

CSS

 .flex-container {
   display: flex;
   width: 500px;
   margin-right: auto;
   margin-left: auto;
 }

 .large-flex-item {
   flex-basis: 66.667%;
   height: 200px;
   background: #333;
 }

.flex-container-inner {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}

.small-flex-item {
   flex-basis: 100%;
   height: 100px;
   background: #000;
 }

DEMO

Flexbox 不喜欢扩展到多列或多行的 flex 项目,因为实际上 flexbox 没有网格概念。

但是,使用一些技巧,您可以实现此布局():

  • 使用行布局

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

  • 使用伪元素强制在2后换行

    ┌─┬─┐
    │1│2│
    ├─┼─┘
    │3│
    └─┘
    
  • 在 2 和 3 上使用 width: 33%,在 1 上使用 flex: 1

    ┌───────────────┬─────┐
    │1              │2    │
    ├─────┬─────────┴─────┘
    │3    │
    └─────┘
    
  • margin-left: auto设为3

    ┌───────────────┬─────┐
    │1              │2    │
    └───────────────┼─────┤
                    │3    │
                    └─────┘
    
  • 选择一些长度x

  • height: x设置为2和3。将height: 2*x设置为1。

    ┌───────────────┬─────┐
    │1              │2    │
    │               ├─────┘
    │               │
    └───────────────┼─────┐
                    │3    │
                    └─────┘
    
  • margin-bottom: -x设为1:

    ┌───────────────┬─────┐
    │1              │2    │
    │               ├─────┤
    │               │3    │
    └───────────────┴─────┘
    
  • 注意 flexbox 引入 auto 作为 min-width 的新初始值。这可能会让内容迫使一些盒子变大。这会破坏布局,因此使用 min-width: 0 禁用它或将 overflow 设置为除 visible.

  • 之外的任何内容

代码如下:

.flex-container {
  display: flex;
  flex-flow: row wrap;
}
.flex-item {
  overflow: hidden;
}
.flex-container::after {
  content: '';
  width: 100%; /* Force line break */
}
.large.flex-item {
  flex: 1;
  height: 200px;
  margin-bottom: -100px;
  background: red;
}
.small.flex-item {
  width: 33.333%;
  height: 100px;
  background: green;
}
.small.flex-item + .small.flex-item {
  order: 1;
  margin-left: auto;
  background: blue;
}
<div class="flex-container">
  <div class="large flex-item">1</div>
  <div class="small flex-item">2</div>
  <div class="small flex-item">3</div>
</div>

但是,修改 HTML 以获得嵌套的 flexbox 会更容易。