5

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.

Tengku Fathullah
  • 1,279
  • 1
  • 18
  • 43
korgmatose
  • 265
  • 4
  • 17
  • 1
    you have to use nested `flexbox`s... you can't fill the remaining whitespace in the non-flex axis... put A,B,C into a container and make the parent a *column* flexbox without wrapping and try... – kukkuz Dec 09 '16 at 07:52
  • why do you have height? Just remove the height – Aslam Dec 09 '16 at 07:58
  • @hunzaboy I use height on the wrapper container to fill the allocated screen real estate – korgmatose Dec 09 '16 at 08:39

2 Answers2

4

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>
SvenL
  • 1,904
  • 8
  • 10
  • The reason for all the inline css is that this is in reality a jsf - project and access to h:outputStylesheet is limited, but that's not really relevant. Good generic answer! – korgmatose Dec 09 '16 at 09:31
  • Thanks glad could have helped. – SvenL Dec 09 '16 at 13:36
0

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;">
  <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>

Something like this?

Aslam
  • 9,204
  • 4
  • 35
  • 51