Search code examples
htmlcsscss-grid

CSS Flex row direction with 50% column stretch


I'm trying to learn how CSS flex works. I want to create a full-width and full-height panel with some blocks (items). I don't understand how do I create 2 vertical items with 50% height each when flex-direction is row (pink and yellow blocks on images).

Here is my goal:

flex layout goal

Here is what I got for now:

flex layout I make

And here is my code:

 body {
      min-height: 100vh;
    }

    .container {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      padding: 5px;
    }

    .container .item
    {    
       margin: 10px;
    }

    .item.blue {
      flex: 0 1 80%;
      background: blue;
    }

    .item.green {
      flex: 0 1 auto;
      background: green;
    }

    .item.red {
        flex: 0 1 60%;
        background: red;
    }

    .item.pink {
      flex: 1 0 auto;
      background: pink;
      align-self: stretch;
    }

    .item.orange{
      flex: 0 1 60%;
      background: orange;
    }

    .item.yellow {
      flex: 1 0 auto;
      align-self: center;
      background: yellow;
    }

    .item.purple{
      flex: 1 0 auto;
      background: purple;
    }
  <div class="container">
    <div class="item blue">
        blue
    </div>
    <div class="item green">
        green
    </div>
    <div class="item red">
        red
    </div>
    <div class="item pink">
        pink
    </div>
    <div class="item orange">
        orange
    </div>
    <div class="item yellow">
        yellow
    </div>
    <div class="item purple">
        purple
    </div>
  </div>


Solution

  • Instead of trying to do all of this with a long, wrapping, flex row, you could add additional rows and column wrappers and still use flex benefits. This way you aren't using occasional self-align properties or things that may be hard to maintain, and the html more semantically resembles the layout.

    .row {
      display: flex;
      flex-direction: row;
    }
    
    .column {
      min-height: 100px;
      flex: 0 1 50%;
      display: flex;
      flex-direction: column;
    }
    
    .column:nth-of-type(1) {
      flex: 0 1 60%;
    }
    
    .column:nth-of-type(2) {
      flex: 1 1 auto;
    }
    
    .item {
      min-height: 30px;
      border-radius: 5px;
      margin: 5px;
    }
    
    .item.blue {
      flex: 0 1 80%;
      background: blue;
    }
    
    .item.green {
      flex: 1 1 auto;
      background: green;
    }
    
    .item.red {
      flex: 0 1 20%;
      background: red;
    }
    
    .item.orange {
      flex: 1 0 auto;
      background: orange;
    }
    
    .item.pink {
      flex: 1 0 auto;
      background: pink;
    }
    
    .item.yellow {
      flex: 1 0 auto;
      background: yellow;
    }
    
    .item.purple {
      flex: 1 0 auto;
      background: purple;
    }
    <div class="row">
      <div class="item blue">
        blue
      </div>
      <div class="item green">
        green
      </div>
    </div>
    <div class="row">
      <div class="column">
        <div class="item red">
          red
        </div>
        <div class="item orange">
          pink
        </div>
      </div>
      <div class="column">
        <div class="item pink">
          orange
        </div>
        <div class="item yellow">
          yellow
        </div>
      </div>
    </div>
    <div class="row">
      <div class="item purple">
        purple
      </div>
    </div>