6

I have the following snippet. It displays 4 cols in one row. When you click on any top button, the script will add a new a <div class="break-row" /> element based on the clicked button which will break the columns into new line. The problem here that the .break-row element occupy vertical space even when its height is 0px. I think in this case the .col element should fill up the vertical available space.

My target is to remove the grey empty area and .col element stretch themself into that area. What is the explanation for that grey area and how can I get rid of it?

$('a').on('click', function(e) {
  e.preventDefault();
  $('.break-row').remove();

  var breakAfter = $(this).data('breakafter');
  if (breakAfter > 0) {
    $('<div class="break-row" />').insertAfter('.col:nth-child(' + breakAfter + 'n)');
  }


});
.row {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  background: #222;
  width: 500px;
  height: 500px;
}

.col {
  display: flex;
  flex-flow: column;
  flex: 1 1 auto;
}

.break-row {
  width: 100%;
  flex: 0 0 auto;
  height: 0px;
}

a {
  background: #456;
  padding: 10px;
  border-radius: 5px;
  margin: 10px;
  display: inline-block;
  color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" data-breakafter="1">
Break after every col
</a>
<a href="#" data-breakafter="2">
Break after every 2 col
</a>
<a href="#" data-breakafter="3">
Break after every  3 col
</a>
<a href="#" data-breakafter="0">
No break
</a>

<div class="row">
  <div class="col" style="background:#0f0;width:10%;">
    aaa
  </div>
  <div class="col" style="background:#f00;width:40%;">
    bbb
  </div>
  <div class="col" style="background:#0f0;width:30%;">
    ccc
  </div>
  <div class="col" style="background:#f00;width:20%;">
    ddd
  </div>
</div>
Roland Soós
  • 3,125
  • 4
  • 36
  • 49
  • does each column need a height of 500px, or does the entire row need to have a max height of 500px? – Joe Lissner Jan 03 '18 at 14:49
  • Yes, they are all required. – Roland Soós Jan 03 '18 at 14:54
  • *What is the explanation for that grey area and how can I get rid of it?* That's two questions. The answer to the first question (the explanation for the behavior) is explained briefly [**here**](https://stackoverflow.com/q/40890613/3597276), and comprehensively [**here**](https://stackoverflow.com/q/42613359/3597276)... – Michael Benjamin Jan 03 '18 at 16:53
  • The answer to the second question is a bit more involved. Switching to `flex-direction: column` or CSS Grid Layout are two options. – Michael Benjamin Jan 03 '18 at 16:54
  • Thanks, @Michael_B! For Question #1. I read your explanations in those questions. This is the part which is relevant to my question? "the free-space is split equally between all of the lines, increasing their cross size." So it splits free-space to the break elements too even if their height is 0? – Roland Soós Jan 03 '18 at 17:16
  • Yeah, it seems that is the explanation: https://jsfiddle.net/va1t6862/ – Roland Soós Jan 03 '18 at 17:23
  • The *flex item* may have a `height: 0`, but the *flex line* (the track in which the item exists) doesn't collapse. See the section **Part 2: Flex Line** in my answer in the second link above. – Michael Benjamin Jan 03 '18 at 17:25
  • Summarize: my .break-row element creates a new "Flex line". Even the element has 0px height, the "Flex line"s height does not follow the height of its items. So that empty space is the "Flex line" which contains the .break-row element and I won't be able to make them disappear if I do not make changes in the structure. You could create an answer and I will accept that as it makes sense :) – Roland Soós Jan 03 '18 at 17:37

1 Answers1

0

This should do the trick for your use case, I added a min-height of 50% to the cols, fixes the issue in all cases except for then there is a break after every one, so in that case I added a class to the row and changed that min-height of the cols to be 25%.

Updated JS

$('a').on('click', function(e) {
  e.preventDefault();
  $('.break-row').remove();
  $('.row').removeClass('always-break')

  var breakAfter = $(this).data('breakafter');
  if (breakAfter > 0) {
    $('<div class="break-row" />').insertAfter('.col:nth-child(' + breakAfter + 'n)');

    if (breakAfter === 1) {
       $('.row').addClass('always-break')
    }
  }


});

Updated CSS

.row {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  background: #222;
  width: 500px;
  height: 500px;
}

.col {
  display: flex;
  flex-flow: column;
  flex: 1 1 auto;
  min-height: 50%;
}

.row.always-break .col{
    min-height: 25%;
}

.break-row {
  width: 100%;
  flex: 0 0 auto;
  height: 0px;
}

a {
  background: #456;
  padding: 10px;
  border-radius: 5px;
  margin: 10px;
  display: inline-block;
  color: #fff;
}
Joe Lissner
  • 2,181
  • 1
  • 15
  • 21