Search code examples
htmlcsspositionflexbox

In flex container, position child 1 on top, and stack 2 and 3 at bottom


I am using flexbox to get the height of the parents to be the same (need them to match) and flex-wrap to wrap every 3.

I then have a button that is always going to be at the bottom.

The first child will always have different sized heights, but always the same width.

Now the trick is, I want child 2 to be at the bottom on top of the button and have both clear the content of child 1.

Absolute positioning will not clear the text of child 1.

I tried flex-grow, but it didn't work for me, maybe because I am new to flexbox.

Please look at the fiddle: https://jsfiddle.net/mm783qc6/4/

.contain {
  display: flex;
  border: 1px solid #000;
  width: 100%;
  flex-wrap: wrap;
}
.p {
  width: 29.5%;
  float: left;
  position: relative;
  margin: 0 10px 30px;
  border: 1px solid red;
}
.bb {
  position: absolute;
  bottom: 0;
  border: 1px solid green;
}
.c1 {
  border: 1px solid blue;
}
.c2 {
  border: 1px solid orange;
}
<div class="contain">

  <div class="p">
    <div class="c1">
      <p>Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text</p>
    </div>
    <div class="c2">
      <p>Go to bottom, but on top of bottom bumper - text can grow sdfkjlkfdj;lksjdf;</p>
    </div>
    <div class="bb">
      <p>---------------Button--------------</p>
    </div>
  </div>

  <div class="p">
    <div class="c1">
      <p>Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and textRandom Height and text Random Height and
        text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text</p>
    </div>
    <div class="c2">
      <p>Go to bottom, but on top of bottom bumper - text can grow sdfkjlkfdj;lksjdf;</p>
    </div>
    <div class="bb">
      <p>-------Button-------</p>
    </div>
  </div>

  <div class="p">
    <div class="c1">
      <p>Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and text Random Height and textRandom Height and text Random Height and
        text Random Height and text Random Height and text Random Height and text Random Height and</p>
    </div>
    <div class="c2">
      <p>Go to bottom, but on top of bottom bumper - text can grow sdfkjlkfdj;lksjdf;</p>
    </div>
    <div class="bb">
      <p>-------Button-------</p>
    </div>
  </div>


  <div class="p">
    <div class="c1">
      <p>Random Height and text Random Height</p>
    </div>
    <div class="c2">
      <p>Go to bottom, but on top of bottom bumper - text can grow sdfkjlkfdj;lksjdf;</p>
    </div>
    <div class="bb">
      <p>---------------Button--------------</p>
    </div>
  </div>

  <div class="p">
    <div class="c1">
      <p>Random Height and text Random Height</p>
    </div>
    <div class="c2">
      <p>Go to bottom, but on top of bottom bumper - text can grow sdfkjlkfdj;lksjdf;</p>
    </div>
    <div class="bb">
      <p>-------Button-------</p>
    </div>
  </div>

  <div class="p">
    <div class="c1">
      <p>Random Height and text Random Height</p>
    </div>
    <div class="c2">
      <p>Go to bottom, but on top of bottom bumper - text can grow sdfkjlkfdj;lksjdf;</p>
    </div>
    <div class="bb">
      <p>-------Button-------</p>
    </div>
  </div>
</div>


Solution

  • Try making your class p elements into flex containers with column-direction. Then using auto margins to push children 2 and 3 down to the bottom. This method aligns the items as you want, and prevents overlapping.

    Revised CSS

    .contain {
        display: flex;
        border: 1px solid #000;
        width: 100%;
        flex-wrap: wrap;
    }
    
    .p {
        width: 29.5%;
        /* float: left;              <-- remove; not necessary */
        /* position: relative;       <-- remove; not necessary */
        margin: 0 10px 30px;
        border: 1px solid red;
    
        display: flex;               /* new */
        flex-direction: column;      /* new */
    }
    
    .bb {
        /* position: absolute;       <-- remove; not necessary */
        /* bottom: 0;                <-- remove; not necessary */
        border: 1px solid green;
    }
    
    .c1 {
        border: 1px solid blue;
        margin-bottom: auto;         /* new; push self to top, everything else to bottom */
        flex: 1;                     /* new; consume all available free space */
    }
    
    .c2 {
        border: 1px solid orange;
    }
    

    Revised Fiddle

    Learn more about flex auto margins here: Methods for Aligning Flex Items along the Main Axis

    Also, if you are wanting equal height columns to extend beyond the first row – i.e., you want the items on the second row to match the height of items on the first row – this is not possible with flexbox. I explain the reason here: Equal height rows in a flex container