使用 flexbox,垂直居中项目并尊重 flexbox 容器的顶部 150px space

Using flexbox, vertically center items and respect top 150px space of flexbox container

我正在尝试在 CSS 中制作具有以下特征的 flexbox:

问题

垂直居中的框不支持 150px space 我想放在 flexbox 的顶部,但我无法创建一种优雅的方式来确保项目不会' 如果我将 window 设置得太短,它会浮出屏幕顶部。也就是说,上图中 "Desired Result 3" 中的示例仍然难以捉摸。

示例代码

HTML:

body {margin:0; font-family: sans-serif; font-weight:bold;}
.parentFlexBox { 
  background-color:grey;
  display: flex;
  flex-direction: column;
  margin-top:0; 
  align-items: center;
  justify-content: center;
  flex-wrap: nowrap;
  height:100vh;
  width:100vw;
  
}
.itemA, .itemB, .itemC, .itemD { padding:5px; text-align:center; margin-bottom:5px; color:#fff;}
.itemA { background-color:red; width:50px;  margin-top:auto;}
.itemB { background-color:hotpink; width:150px; height:50px}
.itemC { background-color:purple; width:40px; height: 35px}
.itemD { background-color:blue; margin-top:auto; width: 80px;}
<div class="parentFlexBox">
  <div class="itemA">A</div>
  <div class="itemB">B</div>
  <div class="itemC">C</div>
  <div class="itemD">D</div>
</div>

以上代码请运行全屏查看问题

这可能对你有用:

HTML(添加两个不可见的弹性项目)

<div class="parentFlexBox">
    <div class="itemA">A</div>
    <div class="itemB">B</div>
    <div class="itemC">C</div>
    <div class="itemD">D</div>
    <div class="itemE">E</div><!-- invisible spacer item with 150px height -->
    <div class="itemF">F</div><!-- invisible spacer item with 120px height -->
</div>

CSS

.parentFlexBox { justify-content: space-between; } /* changed from `center` */

.itemA { order: 1; } /* removed `margin-top: auto` */

.itemB { order: 2; } 

.itemC { order: 3; }

.itemD { order: 5; height: 30px; } /* added `height` for centering calculation;
                                      removed `margin-top:auto` */
.itemE { 
      order: -1;  
      flex: 0 0 150px; /* don't grow, don't shrink, remain at 150px height */
      visibility: hidden;
      margin-bottom: auto; /* stick to top of container */
}

.itemF {
      order: 4;
      flex: 0 1 120px; /* don't grow, shrink proportionally, start at 120px height */
      visibility: hidden;
      margin-top: auto; /* go south as much as possible (sticks to Item D) */
}

/* NOTE: Item D has height 30px. Item F has height 120px. Together they equal height of
   Item E. Equally balanced on both ends, Items A, B & C are centered in the container. */

DEMO 1

我将间隔 div 放在标记的最后,以保持字母顺序。如果您更愿意按顺序列出所有 div(包括间隔符),那么就不需要 order 属性.

此外,在演示中,代码包含边框,以防您希望看到工作中的间隔符。只需禁用 visibility 属性.


更新(基于评论)

Nice, a couple of questions though: 1) Possible to make it so that BCD don't change height when resizing the window? 2) Possible to make the gray background extend to contain D when window is short? 3) Possible to do items E and F as pseudocode elements?

问题 #1:是的。将 flex: 0 0 <<absolute height>> 添加到 BCD。例如,将 flex: 0 0 50px 添加到每个项目,告诉他们保持固定在 50px 高度。 (另外,从每个规则中删除 height 属性,以避免与 flex 的任何潜在冲突。)

问题 #2:是的。不要将容器限制为 height: 100vh,而是使用 min-height: 100vh.

问题 #3:是的。从 HTML 和 CSS 中删除 E 和 F 代码,并将其添加到 CSS:

.parentFlexBox::before {
  content: '';
  flex: 0 0 150px;
  visibility: hidden;
  margin-bottom: auto;
}

.parentFlexBox::after {
  content: '';
  flex: 0 1 100px;
  visibility: hidden;
  margin-top: auto;
  order: 4;
}

DEMO 2