0

Hugely frustrated that I've had to admit defeat on this one, just when I thought I had flexbox grokked! Apologies for the strange description but the issue is easier shown that described.

What I need: All four labelled divs (title, left, right, under-left) must all reside within a common container. Left and Right cols take up half the space each, but UNDER-LEFT must tuck under LEFT regardless of the height of RIGHT.

what i want

What I've got: At present as I increase the height of RIGHT it is pushing UNDER-LEFT down with it :(

enter image description here

My Code So Far

<style>
#container {    
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;  
  width: 580px;
  background-color: rgb(240, 240, 240);
}
#heading {
  display: inline-block;
  height: 100px;
  width: 100%;  
  background-color: rgb(200, 200, 200);
}
#left {
  background-color: red;
  height: 250px;
  flex: 0 0 50%;
}
#right {
  background-color: lightblue;
  flex: 0 0 50%;
}
#under-left {   
  background-color: lightgreen;
  flex: 0 0 50%;
}
</style>

<body>
<div id="container">

    <div id="heading">
        <p>title</p>
    </div>

    <div id="left">
        <p>LEFT height 250, basis 50%</p>
    </div>

    <div id="right">
        <p>RIGHT, basis 50%</p>
    </div>

    <div id="under-left">
    <p>UNDER-LEFT</p>
    </div>  

</div>
</body>

What I've tried: To be honest I'm at a total loss. I have tried floating elements but of course flex ignores floats. I don't know what else to try, it's not laziness as it took me about 25 minutes to create this post. I have searched for other answers on SO (such as CSS Flex Box Layout: full-width row and columns) but none feature the wrap-under element issue.

Please be kind!

Community
  • 1
  • 1
Phil Blunt
  • 151
  • 1
  • 10
  • Flexbox can do this is the height of the left side is known, alternatively, the simplest method is to wrap the left side divs in a container of their own. Is there a reason you can't do that? – Paulie_D Jul 19 '16 at 10:21
  • The point being, you are trying to force flexbox to do something it wasn't designed to do. – Paulie_D Jul 19 '16 at 10:23
  • @Paulie_D Sorry, maybe wasn't clear that wrapping left DIVS in another container is not acceptable here, the reason is that I need to do some flexbox element ORDER changes for other viewports that would become problematic. – Phil Blunt Jul 19 '16 at 10:44
  • Can you post how that should look like, on other viewport's – Asons Jul 19 '16 at 10:46
  • @LGSon, on mobile I'm simply going to have all blocks width 100% so there is not much to show you – Phil Blunt Jul 19 '16 at 11:21

1 Answers1

0

Do like this to use flexbox (needed a markup change)

#container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  width: 580px;
  background-color: rgb(240, 240, 240);
}
#heading {
  display: inline-block;
  height: 100px;
  width: 100%;
  background-color: rgb(200, 200, 200);
}
#left {
  flex: 1;
}
#right {
  background-color: lightblue;
  flex: 1;
  padding: 20px;
}
#left-top {
  background-color: red;
  padding: 20px;
}
#left-bottom {
  background-color: lightgreen;
  padding: 20px;
}
<div id="container">

  <div id="heading">
    <p>title</p>
  </div>

  <div id="left">
    <div id="left-top">
      LEFT height 250, basis 50%
    </div>
    
    <div id="left-bottom">
      UNDER-LEFT
    </div>
  </div>

  <div id="right">
    RIGHT, basis 50%
  </div>

</div>

Update based on comment not being able to wrap the left div's

Note, this might be doable with flexbox and non wrapped divs, though I need to know how that layout should look like.

Here is a floated version, which can use flexbox on smaller screens using @media query to reorder the elements visually.

To make the under-left always stay under the left regardless of the right's height, you need to make them wider than the right (here 1px), have the left one's floated left, the right floated right

Sample, right lower

#container {
  width: 580px;
  background-color: rgb(240, 240, 240);
}
#heading {
  display: inline-block;
  height: 100px;
  width: 100%;
  background-color: rgb(200, 200, 200);
}
#left {
  background-color: red;
  height: 150px;
  float: left;
  width: calc(50% + 1px);
}
#right {
  background-color: lightblue;
  height: 100px;
  float: right;
  width: calc(50% - 1px);
}
#under-left {
  background-color: lightgreen;
  float: left;
  width: calc(50% + 1px);
}
<div id="container">

  <div id="heading">
    <p>title</p>
  </div>

  <div id="right">
    <p>RIGHT, basis 50%</p>
  </div>

  <div id="left">
    <p>LEFT height 250, basis 50%</p>
  </div>

  <div id="under-left">
    <p>UNDER-LEFT</p>
  </div>

</div>

Sample, right higher

#container {
  width: 580px;
  background-color: rgb(240, 240, 240);
}
#heading {
  display: inline-block;
  height: 100px;
  width: 100%;
  background-color: rgb(200, 200, 200);
}
#left {
  background-color: red;
  height: 150px;
  float: left;
  width: calc(50% + 1px);
}
#right {
  background-color: lightblue;
  height: 250px;
  float: right;
  width: calc(50% - 1px);
}
#under-left {
  background-color: lightgreen;
  float: left;
  width: calc(50% + 1px);
}
<div id="container">

  <div id="heading">
    <p>title</p>
  </div>

  <div id="right">
    <p>RIGHT, basis 50%</p>
  </div>

  <div id="left">
    <p>LEFT height 250, basis 50%</p>
  </div>

  <div id="under-left">
    <p>UNDER-LEFT</p>
  </div>

</div>

Update 2 based on yet another comment

Here is a floated version combined with flexbox and @media query, that will make them in the right order/size on smaller screens

#container {
  width: 580px;
  background-color: rgb(240, 240, 240);
}
#heading {
  display: inline-block;
  height: 100px;
  width: 100%;
  background-color: rgb(200, 200, 200);
}
#left {
  background-color: red;
  height: 150px;
  float: left;
  width: calc(50% + 1px);
}
#right {
  background-color: lightblue;
  height: 200px;
  float: right;
  width: calc(50% - 1px);
}
#under-left {
  background-color: lightgreen;
  float: left;
  width: calc(50% + 1px);
}

@media screen and (max-width: 600px) {
  #container {
    display: flex;
    flex-direction: column;
  }
  #left,
  #under-left,
  #right {
    float: none;
    width: auto;
  }
  #right {
    order: 1;
  }
}
<div id="container">

  <div id="heading">
    <p>title</p>
  </div>

  <div id="right">
    <p>RIGHT, basis 50%</p>
  </div>

  <div id="left">
    <p>LEFT height 250, basis 50%</p>
  </div>

  <div id="under-left">
    <p>UNDER-LEFT</p>
  </div>

</div>
Asons
  • 84,923
  • 12
  • 110
  • 165