Search code examples
cssflexboxpositioningfillstretch

CSS Flexbox - varying height of elements on wrap


I have a simple layout with varying size elements that I am trying to put together for a dashboard.

div {
  padding: 5px 5px 5px 5px;
  margin: 1px 1px 1px 1px;
  display: flex;
}
div.first {
  border: 1px dotted lightpink;
}
div.second {
  border: 1px dotted orange;
}
div.third {
  border: 1px dotted green;
}
div.fourth {
  border: 1px dotted fuchsia;
}
<div style="display: flex; height: 500px">
  <div class="first" style="flex: 0 60%;flex-wrap: wrap;align-items;stretch;align-content:stretch">
    <div class="first" style="flex: 1 100%; align-self: flex-start">
      Title text
    </div>
    <div class="second" style="flex: 2 auto">
      Content A
    </div>
    <div class="third" style="flex: 1 auto">
      Content B
    </div>
    <div class="fourth" style="flex: 1 auto">
      <div style="height: 66px; align-self:flex-end">
        <div style="align-self: flex-end">
          Content C
        </div>
      </div>
    </div>
  </div>
  <div class="second" style="flex: 1 auto; align-items: flex-end">
    Content D
  </div>
</div>

Codepen link: http://codepen.io/korgmatose/pen/qqKzry?editors=1100

I want to fill the second row (Content A,B,C) so that it starts just beneath Title Text.

But making align-items flex-start will not allow the second row to fill the remaining space, and setting a height to 100% on one of the items in that row only sets the height to the parent container, thus rendering the div's outside the bottom border.


Solution

  • Like @kukkuz said I would also recommend doing it this way. Just put the content A, B, C in a separate container, in this case #content and add display: flex, flex-direction: column and flex: 1 to it and please do not use inline styling for styling your HTML since it makes your code muss less readable. Most recommended way is to put your CSS code into a separate file and link it to your HTML.

    The following code is an example of how you could do the markup of your desired layout without any inline styles.

    HTML

    <div id="wrapper">
      <div class="left">
        <div class="title">Title text</div>
        <div id="content">
          <div class="second">Content A</div>
          <div class="third">Content B</div>
          <div class="fourth">Content C</div>
        </div>
      </div>
      <div class="right">Content D</div>
    </div>
    

    CSS

    div {
      padding: 5px 5px 5px 5px;
      margin: 1px 1px 1px 1px;
    }
    
    #wrapper {
      display: flex;
      height: 500px;
    }
    
    .left {
      flex: 3;
      display: flex;
      flex-direction: column;
    }
    
    #content{
      flex: 1;
      display: flex;
      padding: 0;
    }
    
    .second,
    .third,
    .fourth {
      flex: 1;
    }
    
    .third {
      border: 1px dotted green;
    }
    
    .fourth {
      display: flex;
      align-items: flex-end;
      border: 1px dotted fuchsia;
    }
    
    .right {
      flex: 2;
    }
    
    .left,
    .title {
      border: 1px dotted lightpink;
    }
    
    .right,
    .second {
      border: 1px dotted orange;
    } 
    

    div {
      padding: 5px 5px 5px 5px;
      margin: 1px 1px 1px 1px;
    }
    #wrapper {
      display: flex;
      height: 500px;
    }
    .left {
      flex: 3;
      display: flex;
      flex-direction: column;
    }
    #content {
      flex: 1;
      display: flex;
      padding: 0;
    }
    .second,
    .third,
    .fourth {
      flex: 1;
    }
    .third {
      border: 1px dotted green;
    }
    .fourth {
      display: flex;
      align-items: flex-end;
      border: 1px dotted fuchsia;
    }
    .right {
      flex: 2;
    }
    .left,
    .title {
      border: 1px dotted lightpink;
    }
    .right,
    .second {
      border: 1px dotted orange;
    }
    <div id="wrapper">
      <div class="left">
        <div class="title">Title text</div>
        <div id="content">
          <div class="second">Content A</div>
          <div class="third">Content B</div>
          <div class="fourth">Content C</div>
        </div>
      </div>
      <div class="right">Content D</div>
    </div>