Search code examples
cssflexboxvertical-alignment

flexbox vertical align child top, center another


I've got the following markup:

.row {
  display: flex;
  align-items: stretch;
  
  margin: -16px;
  background: #ddd;
}

.row .col {
  display: flex;
  flex-direction: column;
  justify-content: center;
  
  flex: 1;
  
  margin: 16px;
  background: #fff;
}

.header, .content, .footer {
  padding: 16px;
  
  background: red;
}
<div class="row">
    <div class="col">
        <div class="header">Header #1</div>
        <div class="content">Lorem Ipsum<br />Dolor<br />Sit Amet</div>
        <div class="footer">Footer</div>
    </div>

    <div class="col">
        <div class="header">Header #2</div>
        <div class="content">Lorem Ipsum<br />Dolor</div>
    </div>
</div>

Unfortunatly the second header isn't align vertically to the top. Is there a way to archive this with flexbox? I need the ".header" to be aligned the the top and the ".content" to be centered within the rest of the box.

Greetings!


Solution

  • No, not really, not without another wrapper which is a flex-container.

    As flexbox is, to a certain extent based on manipulting margins, there is no method (AFAIK, although I'd be interested to find out if there is) to justify-content: center and then align-self a child element to somewhere else other than center.

    I'd go with something like this: Add a wrapper to the "content" div, give it flex:1 to fill the remaining space below the header, then make that wrapper display:flex with justify-content:center.

    This seems to be the most logical method

    .col {
      height: 150px;
      width: 80%;
      margin: 1em auto;
      border: 1px solid grey;
      display: flex;
      flex-direction: column;
    }
    .header {
      background: lightblue;
    }
    .content {
      background: orange;
    }
    .flexy {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: center;
      background: plum;
    }
    <div class="col">
      <div class="header">Header #2</div>
      <div class="flexy">
        <div class="content">Lorem Ipsum
          <br />Dolor</div>
      </div>
    </div>

    Codepen Demo