使用flexbox,垂直居中项目并尊重Flexbox容器的前150px空间

时间:2015-12-27 23:42:06

标签: html css css3 flexbox

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

  • 在flexbox中间堆叠并居中的三个项目
  • 一个项目锁定在flexbox底部
  • Flexbox设置为100vh和100vw,占用可见屏幕区域
  • flexbox中的项目不得占用Flexbox的前150px。这可能会将某些项目推到可查看区域下方(请参阅下图中的“所需结果3”)
  • 理想情况下,提供HTML元素的纯CSS解决方案是可行的

enter image description here

问题

垂直居中的盒子不会尊重我想放在flexbox顶部的150px空间,而且我无法创造一种优雅的方式来确保物品不会飘过如果我让窗户太短,屏幕的顶部。也就是说,上图中“所需结果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>

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

1 个答案:

答案 0 :(得分:3)

这可能对您有用:

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属性。

更新(根据评论)

  

很好,但有几个问题:1)可以做到这一点,以便在调整窗口大小时BCD不会改变高度? 2)当窗口短时,可以使灰色背景延伸到包含D? 3)可以将E和F项作为伪代码元素吗?

问题#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