居中和底部对齐弹性项目

时间:2016-03-24 01:04:51

标签: html css css3 flexbox css-grid

我有一个带有以下属性的flex容器(蓝色方块):

display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;

因此,它的孩子(浅蓝色方块)如下所示排列自己。但是,我想在正常流程中添加另一个孩子(绿色方块)并将其相对于其父项定位。要按照下面的说明定位,我最好写一些类似bottom: 20px;margin: auto;的内容。

enter image description here

我试着玩z-index无济于事。我该怎么做呢?我应该求助于创建另一个父元素吗?

3 个答案:

答案 0 :(得分:45)

以下是实现此布局的五个选项:

  1. CSS定位
  2. 带有隐形DOM元素的Flexbox
  3. 具有隐形伪元素的Flexbox
  4. 带有flex: 1
  5. 的Flexbox
  6. CSS网格布局
  7. 方法#1:CSS定位属性

    position: relative应用于Flex容器。

    position: absolute应用于绿色弹性项目。

    现在绿色方块绝对位于弹性容器内。

    更具体地说,绿色方块已从文档流中删除,但仍保持在nearest positioned ancestor的范围内。

    使用CSS偏移属性topbottomleftright移动绿色方块。

    
    
    flex-container {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: nowrap;
      position: relative;
      border: 4px solid blue;
      height: 300px;
      width: 300px;
    }
    flex-container > flex-item:first-child {
      display: flex;
    }
    flex-container > flex-item:first-child > flex-item {
      border: 4px solid aqua;
      height: 50px;
      width: 50px;
      margin: 0 5px;
    }
    flex-container > flex-item:last-child {
      position: absolute;
      bottom: 40px;
      left: 50%;
      transform: translateX(-50%); /* fine tune horizontal centering */
      border: 4px solid chartreuse;
      height: 50px;
      width: 50px;
    }
    
    <flex-container>
        <flex-item><!-- also flex container -->
    	    <flex-item></flex-item>
    	    <flex-item></flex-item>
    	    <flex-item></flex-item>
        </flex-item>
        <flex-item></flex-item>
    </flex-container>
    &#13;
    &#13;
    &#13;

    一个警告:某些浏览器可能无法从正常流程中完全删除绝对定位的Flex项目。这会以非标准的,意外的方式更改对齐方式。更多详情: Absolutely positioned flex item is not removed from normal flow in Firefox & IE11

    方法#2:Flex Auto Margins&amp;不可见的Flex项目(DOM元素)

    结合auto margins和新的隐形弹性项目,可以实现布局。

    新的弹性项目与底部项目相同,位于另一端(顶部)。

    更具体地说,因为柔性对齐基于自由空间的分布,所以新项目是必要的平衡以保持三个蓝色框垂直居中。新项目必须与现有绿色项目的高度相同,否则蓝色框不会精确居中。

    使用visibility: hidden从视图中删除新项目。

    简而言之:

    • 创建绿色框的副本。
    • 将其放在列表的开头。
    • 使用弹性auto边距保持蓝色框居中,两个绿色框从两端创建相等的平衡。
    • visibility: hidden应用于重复的绿色框。

    &#13;
    &#13;
    flex-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        border: 4px solid blue;
        height: 300px;
        width: 300px;
    }
    flex-container > flex-item:first-child {
        margin-top: auto;
        visibility: hidden;
    }
    flex-container > flex-item:nth-child(2) {
        margin-top: auto;
        display: flex;
    }
    flex-container > flex-item:last-child {
        margin-top: auto;
        margin-bottom: auto;
    }
    flex-container > flex-item:first-child,
    flex-container > flex-item:last-child {
        border: 4px solid chartreuse;
        height: 50px;
        width: 50px;
    }
    flex-container > flex-item:nth-child(2) > flex-item {
        border: 4px solid aqua;
        height: 50px;
        width: 50px;
        margin: 0 5px;
    }
    &#13;
    <flex-container>
        <flex-item></flex-item>
        <flex-item><!-- also flex container -->
    	    <flex-item></flex-item>
    	    <flex-item></flex-item>
    	    <flex-item></flex-item>
        </flex-item>
        <flex-item></flex-item>
    </flex-container>
    &#13;
    &#13;
    &#13;

    方法#3:Flex Auto Margins&amp;不可见的Flex项(伪元素)

    这种方法类似于#2,除了它在语义上更清洁,并且必须知道绿箱的高度。

    • 创建一个与现有绿色框具有相同高度的伪元素。
    • 使用::before将其放在容器的开头。
    • 使用flex auto页边距保持蓝色框居中,绿色伪元素和DOM元素从两端创建相等的平衡。

    &#13;
    &#13;
    flex-container {
        display: flex;
        flex-direction: column;
        align-items: center;
        border: 4px solid blue;
        height: 300px;
        width: 300px;
    }
    flex-container::before {
      content: "";
      margin-top: auto;
      height: calc(50px + 8px);  /* height + borders */
      visibility: hidden;
    }
    flex-container > flex-item:first-child {
      margin-top: auto;
      display: flex;
    }
    flex-container > flex-item:last-child {
      margin-top: auto;
      margin-bottom: auto;
      border: 4px solid chartreuse;
      height: 50px;
      width: 50px;
    }
    flex-container > flex-item:first-child > flex-item {
      border: 4px solid aqua;
      height: 50px;
      width: 50px;
      margin: 0 5px;
    }
    &#13;
    <flex-container>
        <flex-item><!-- also flex container -->
            <flex-item></flex-item>
    	    <flex-item></flex-item>
    	    <flex-item></flex-item>
        </flex-item>
        <flex-item></flex-item>
    </flex-container>
    &#13;
    &#13;
    &#13;

    方法#4:将flex: 1添加到顶部和底部项目

    从上面的方法#2或#3开始,不要担心顶部和底部物品的高度相等,以保持平衡,只需给每一个flex: 1。这将迫使它们消耗可用空间,从而使中间项目居中。

    然后,您可以将display: flex添加到底部项目,以便对齐内容。

    方法#5:CSS网格布局

    这可能是最干净,最有效的方法。不需要绝对定位,虚假元素或其他hackery。

    只需创建一个包含三行的网格。然后居中对齐第二行和第三行中的项目。第一行可以保持为空。

    &#13;
    &#13;
    grid-container {
      display: grid;
      grid-template-rows: repeat(3, 1fr);
      align-items: center;
      justify-items: center;
      border: 4px solid blue;
      height: 300px;
      width: 300px;
    }
    
    grid-item:nth-child(2) {
      display: flex;
    }
    
    grid-item:nth-child(2)>flex-item {
      width: 50px;
      height: 50px;
      margin: 0 5px;
      border: 4px solid aqua;
    }
    
    grid-item:nth-child(3) {
      border: 4px solid chartreuse;
      height: 50px;
      width: 50px;
    }
    &#13;
    <grid-container>
      <grid-item></grid-item>
      <grid-item><!-- also flex container -->
        <flex-item></flex-item>
        <flex-item></flex-item>
        <flex-item></flex-item>
      </grid-item>
      <grid-item></grid-item>
    </grid-container>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:4)

让包含position: relative的容器和带有position:absolute;

的绿色方块

body {
  margin: 0;  
}

#container {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  width: 192px;
  height: 192px;
  border: 4px solid indigo;
  position: relative;
  background: lavender;
}

.blue {
  margin: 10px;
  width: 30px;
  height: 30px;
  outline: 4px solid skyblue;
  background: honeydew;
}

#green {
  position: absolute;
  width: 30px;
  height: 30px;
  left: 0;
  right: 0;
  margin: auto;
  bottom: 20px;
  outline: 4px solid yellowgreen;
  background: greenyellow;
}
<div id=container>
<div class=blue></div><div class=blue></div><div class=blue></div>
<div id=green></div>
</div>

答案 2 :(得分:3)

您可以使用伪向下移动前三个容器的一行,然后将margin:auto应用到最后一个

div {
  display:flex;
  flex-wrap:wrap;
  border:#0066FD solid;;
  width:200px;
  height:200px;
  justify-content:space-around;
  /* show me box center */
  background:linear-gradient(to top,rgba(0,0,0,0.2) 50%, transparent 50%),linear-gradient(to left,rgba(0,0,0,0.2) 50%, transparent 50%)
 
}

span, div:before {
  width:50px;
  height:50px;
  border:solid #01CDFF;
  margin:0 auto 0;
}
span:last-of-type , div:before{
  margin: 12px auto;
  border:solid  #01FE43;
}
div:before {
  content:'';
  width:100%;
  border:none;
}

span {
   /* show me box center */
  background:linear-gradient(45deg,rgba(0,0,0,0.1) 50%, transparent 50%),linear-gradient(-45deg,rgba(0,0,0,0.1) 50%, transparent 50%)
  }
<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>