3

There is a huge gap appearing in the div with the text in increasing with display:flex

enter image description here

Adding extra div wrap may not be a solution which may effect to mobile version. Mobile view should be looks like this

enter image description here

p {
  margin: 10px;
}

body {
  display: flex;
  flex-wrap: wrap;
  // flex-direction: column;
}

.my-wrap {
  width: 90%;
  margin: 50px auto;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  border: 1px solid #eee;
  color: #fff;
}

.wrap-one,
.wrap-two {
  width: 75%;
}

.wrap-one {
  background-color: tomato;
  flex: 1;
}

.wrap-two {
  background-color: deepskyblue;
}

.wrap-three {
  background-color: greenyellow;
  flex-basis: 100%;
  width: 25%;
}
<div class="my-wrap">
  <div class="wrap-one">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum voluptates ipsa tempora qui voluptas, dicta corrupti dolorum, iure esse earum ut pariatur, ad possimus facilis consequatur impedit accusantium autem! Nesciunt?</p>
  </div>
  <div class="wrap-two">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat commodi aspernatur et! Voluptates officiis nemo corporis delectus pariatur. Cupiditate perspiciatis illum minima, porro voluptas velit nobis ad eveniet modi explicabo.</p>
  </div>
  <div class="wrap-three">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis reprehenderit, necessitatibus vel praesentium dolorum vitae sequi in magni voluptate alias fugit saepe eos sint dolore quae sapiente sunt itaque, cupiditate.</p>
  </div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
Mo.
  • 26,306
  • 36
  • 159
  • 225
  • How is this supposed to look? You might have to adjust the HTML here. If you remove the `flex:1` from `.wrap-one` it solves the firt problem. Frankly, you'll probably need to put `one` and `two` in their own container. – Paulie_D Jun 22 '17 at 15:57
  • Since you are using flex direction column to achieve that output, the only way is to set a height on the container. To solve this properly you need to wrap one and two – Asons Jun 22 '17 at 15:57
  • Yep, like this - https://codepen.io/Paulie-D/pen/rwwodM – Paulie_D Jun 22 '17 at 16:01
  • @Paulie_D removing `flex:1` make gap with in div https://codepen.io/anon/pen/pwwqLv Actually all the color should be fit with in the `.my-wrap` div – Mo. Jun 22 '17 at 16:01
  • Then you need to be clearer as to how this is supposed to look. – Paulie_D Jun 22 '17 at 16:01
  • @Paulie_D As you can see in the image, the gap shouldn't happen. currently the gap is increasing when add more text to the green section :-( – Mo. Jun 22 '17 at 16:04
  • Please review and comment on my answer, and let me know if something is unclear or missing. If not, then it would be great if you could accept the answer that helped you the most. – Asons Jun 25 '17 at 18:34
  • @LGSon Thank you very much for your answer. The question has explained more with update. Could you please have a look the updated question – Mo. Jun 26 '17 at 18:56
  • I updated my answer. I notified Michael_B, as he will be able to show a CSS Grid version. So your choice will be to either use Flexbox with a small script, which has a wider browsers support, or CSS Grid, which can do this CSS only, though has less browser support. – Asons Jun 26 '17 at 19:42

2 Answers2

1

Since you are using flex direction column, they won't collapse vertically to decrease that gap, that is not the way Flexbox work.

For flex direction column you need to set a height on the my-wrap container for the flex items to wrap, so, in your case, and to be able to have dynamic sized items, use flex direction row:

  • wrap one and two
  • change my-wrap to row direction and add flex-wrap: wrap
  • make wrap-left a flex column container
  • set flex-grow on one/two flex items

Updated

To also enable the mobile view, and since that is not possible to solve with Flexbox at all, I added a small script that, based on width, simply move the wrap-one element in and out from the wrap-left element.

It also adds a class to the body elements, mobileview, which can be used to target element in a similar fashion one can do using a media query.

The script's resize handler has little, if any, performance impact as it throttled.

Fiddle demo

Stack snippet

(function(d, w, timeout) {

  /* custom variables */
  var flexcontainer = '.wrap-left',
    flexitem = '.wrap-one',
    minwidth = 600,             /* if null, then when viewport is portrait */
    classname = 'mobileview';
    
  /* here happens the magic */
  function resizeing() {
    if ((minwidth && (minwidth < w.innerWidth)) ||
        (!minwidth && (w.innerHeight < w.innerWidth))) {
      if (d.body.classList.contains(classname)) {      
        /* move it back inside the main flexcontainer */
        d.body.classList.remove(classname)
        var fca = qSA(flexcontainer);
        for (var i = 0; i < fca.length; i++) {
          fca[i].appendChild(qS(flexitem, fca[i].parentNode))
        }
      }      
    } else {
      if (!(d.body.classList.contains(classname))) {
        /* move it outside the main flexcontainer */
        d.body.classList.add(classname);
        var fca = qSA(flexcontainer);
        for (var i = 0; i < fca.length; i++) {
          fca[i].parentNode.appendChild(qS(flexitem, fca[i]))
        }
      }
    }
  }
  
  /* run at page load init resize */
  w.addEventListener("load", function() {
    resizeing();
  }, false);
  
  /* grab when viewport resize */
  w.addEventListener("resize", function() {
    if (!timeout) {
      timeout = setTimeout(function() {
        timeout = null;
        resizeing();
      }, 66);
    }
  }, false);
  
  /* helper variables */
  var qSA = function(s, el) {
      return (el) ? el.querySelectorAll(s) :
        d.querySelectorAll(s)
    },
    qS = function(s, el) {
      return (el) ? el.querySelector(s) :
        d.querySelector(s)
    };
}(document, window));
p {
  margin: 10px;
}
body {
  display: flex;
}

.my-wrap {
  width: 90%;
  margin: 30px auto;
  display: flex;
  flex-wrap: wrap;
  border: 1px solid #eee;
  color: #fff;
}

.wrap-left {
  flex: 0 0 75%;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
  .wrap-one {
    flex-grow: 1;
    background-color: tomato;
  }
  .wrap-two {
    flex-grow: 1;
    background-color: deepskyblue;
  }
  
.wrap-right {
  flex: 0 0 25%;
  min-width: 0;
  background-color: greenyellow;
}

/*  for mobile layout  */
.my-wrap > .wrap-one {
  flex: 0 0 100%;
  order: -1;
}
.mobileview .wrap-right {
  background-color: green;
}
<div class="my-wrap">
  <div class="wrap-left">
    <div class="wrap-one">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum voluptates ipsa tempora qui voluptas, dicta corrupti dolorum, iure esse earum ut pariatur, ad possimus facilis consequatur impedit accusantium autem! Nesciunt?</p>
    </div>
    <div class="wrap-two">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat commodi aspernatur et! Voluptates officiis nemo corporis delectus pariatur. Cupiditate perspiciatis illum minima, porro voluptas velit nobis ad eveniet modi explicabo.</p>
    </div>
  </div>
  <div class="wrap-right">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis reprehenderit, necessitatibus vel praesentium dolorum vitae sequi in magni voluptate alias fugit saepe eos sint dolore quae sapiente sunt itaque, cupiditate.</p>
  </div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • The solution may effect to mobile responsive version if we add extra div – Mo. Jun 26 '17 at 18:49
  • @MuhammedAthimannil Then the proper way would of course be to show how that is suppose to look like and we can provide a solution covering that too, as the now used won't work in either device as it won't collapse to its content – Asons Jun 26 '17 at 18:54
1

First, you're getting abnormal behavior because you've specified flex-basis: 100% on the green item (.wrap-three), without specifying a height on the parent.

In CSS, for percentage heights to work properly across browsers, you should always specify the parent's height.

Add this to your code:

html, body, .my-wrap { height: 100%; }

html,
body,
.my-wrap {
  height: 100%;
}

p {
  margin: 10px;
}

body {
  display: flex;
  flex-wrap: wrap;
}

.my-wrap {
  width: 90%;
  margin: 50px auto;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  border: 1px solid #eee;
  color: #fff;
}

.wrap-one,
.wrap-two {
  width: 75%;
}

.wrap-one {
  background-color: tomato;
  flex: 1;
}

.wrap-two {
  background-color: deepskyblue;
}

.wrap-three {
  background-color: greenyellow;
  flex-basis: 100%;
  width: 25%;
}
<div class="my-wrap">
  <div class="wrap-one">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum voluptates ipsa tempora qui voluptas, dicta corrupti dolorum, iure esse earum ut pariatur, ad possimus facilis consequatur impedit accusantium autem! Nesciunt?</p>
  </div>
  <div class="wrap-two">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat commodi aspernatur et! Voluptates officiis nemo corporis delectus pariatur. Cupiditate perspiciatis illum minima, porro voluptas velit nobis ad eveniet modi explicabo.</p>
  </div>
  <div class="wrap-three">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis reprehenderit, necessitatibus vel praesentium dolorum vitae sequi in magni voluptate alias fugit saepe eos sint dolore quae sapiente sunt itaque, cupiditate.</p>
  </div>
</div>

Second, since you haven't specified a height on the flex container, browsers are free to interpret the height at their discretion.

For a more stable layout, try this (for example): .my-wrap { height: 300px }

p {
  margin: 10px;
}

body {
  display: flex;
  flex-wrap: wrap;
}

.my-wrap {
  height: 300px;
  width: 90%;
  margin: 50px auto;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  border: 1px solid #eee;
  color: #fff;
}

.wrap-one,
.wrap-two {
  width: 75%;
}

.wrap-one {
  background-color: tomato;
  flex: 1;
}

.wrap-two {
  background-color: deepskyblue;
}

.wrap-three {
  background-color: greenyellow;
  flex-basis: 100%;
  width: 25%;
}
<div class="my-wrap">
  <div class="wrap-one">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum voluptates ipsa tempora qui voluptas, dicta corrupti dolorum, iure esse earum ut pariatur, ad possimus facilis consequatur impedit accusantium autem! Nesciunt?</p>
  </div>
  <div class="wrap-two">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat commodi aspernatur et! Voluptates officiis nemo corporis delectus pariatur. Cupiditate perspiciatis illum minima, porro voluptas velit nobis ad eveniet modi explicabo.</p>
  </div>
  <div class="wrap-three">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis reprehenderit, necessitatibus vel praesentium dolorum vitae sequi in magni voluptate alias fugit saepe eos sint dolore quae sapiente sunt itaque, cupiditate.</p>
  </div>
</div>

More information:

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701