I need to animate the shrink and expand transitions for subsets of elements in a nested set of divs. The expand works fine, but the shrink is broken.
I have a structured collection of items (say, squares for purposes here) that I want to display selectively and whose transitions I want to animate.
The structure is: collection > groups > rows > squares
In static layout,
- squares appear in horizontal rows;
- rows are gathered vertically in groups;
- a column of groups forms the collection.
Squares can be of varying sizes, so containers must adjust accordingly (no fixed heights or widths).
I have obtained a static layout that is just what I want.
The problem comes with animation. I want to hide various subsets of squares, rows and/or groups. Nearby items can look similar so it is difficult for users to tell just what is being added or subtracted, so I need a smooth animation so users can follow what is changing.
I am trying to do this with a CSS-animated shrink:
- A shrinkMeclass marks all element that I will want to shrink/expand at the moment
- CSS transition times are set for these
shrinkMeelements
- A shrunkenclass is defined whose CSS has all its size parameters set to 0
- To shrink or expand, jQuery adds or removes
the the shrunkenclass tag to the$('shrinkMe')items, to animate items between the full and shrunken (=0) sizes
The un-shrink animated transition is exactly what I want. But the shrink animation does not work at all - contents spill out of containers along the way.
shrink = function(bool,nsec) {
  $('.shrinkMe').css("transition", 'all ' + nsec+ 's');
  if (bool) $('.shrinkMe').addClass('shrunk')
  else $('.shrinkMe').removeClass('shrunk');
}
anim = function(secs) {
  return 'all ' + secs + 's'
}.controls {
  display: inline-block;
  vertical-align: top;
}
.collection {
  display: inline;
  text-align: center;
  border: 2px solid black;
  padding: 3px;
  display: inline-block;
}
.group {
  display: block;
  margin: 2px;
  border: 2px solid black;
  padding: 3px;
}
.row {
  display: block;
  vertical-align: middle;
  background: #0cc;
  margin: 1px;
  border: 2px solid black;
}
.sq {
  display: inline-block;
  background: white;
  width: 20px;
  height: 20px;
  margin: 5px;
  border: 2px solid black;
}
.lg {
  width: 25px;
  height: 25px;
}
.shrinkMe {
  border-color: red;
}
.shrunk {
  height: 0px;
  width: 0px;
  border-width: 0px;
  padding: 0px;
  margin: 0px;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div class='controls'>
  <button type='button' onclick='shrink(true,2)'>shrink reds </button>
  <br>
  <button type='button' onclick='shrink(false,2)'>unshrink reds </button>
</div>
<div class='collection'>
  <div class='group'>
    <div class='row '>
      <div class='sq'></div>
      <div class='sq'></div>
    </div>
    <div class='row shrinkMe'>
      <div class='sq lg shrinkMe'></div>
      <div class='sq shrinkMe'></div>
      <div class='sq lg shrinkMe'></div>
    </div>
  </div>
  <div class='group shrinkMe' id='group2'>
    <div class='row shrinkMe' id='group2container2'>
      <div class='sq shrinkMe'></div>
      <div class='sq shrinkMe'></div>
    </div>
    <div class='row shrinkMe'>
      <div class='sq shrinkMe'></div>
      <div class='sq lg shrinkMe'></div>
      <div class='sq shrinkMe'></div>
    </div>
  </div>
</div>Among other things, I've tried using different explicit transition speeds, so containers shrink more slowly than their contents, but to no avail. If I set explicit heights and widths of the rows and groups, I can get a coordinated nested-shrink but it is ugly:
- It shrinks by squashing to the left side and;
- The final layouts can have empty spaces in them (e.g., when a row shrinks inside an unshrunk group, the fixed explicit group container height means there is now a hole where the row was).
What I want is to achieve is simple: a shrink animation that is the time-reverse of the nice clean un-shrink.
Here also is a jsfiddle showing the problem that additionally has buttons for trying separate timings of more deeply nested divs (which does not help...)
https://jsfiddle.net/furnas/dgq8yusy/
Any explanation of what is going wrong and suggestions on how to fix it?
 
     
    