Animate Flexbox Inserts and Removes

by Eric

HTML

<script src="http://fonts.googleapis.com/css?family=Ubuntu:400,700,400italic,700italic"></script>
<script src="https://rawgit.com/shyiko/lorem/master/src/library/lorem.js"></script>
Single line flex box smooth animated inserts and removes:

<div class="flexbox">
    <div class="flex-item"></div>
    <div class="flex-item hover-collapse-item">I will collapse on hover</div>
    <div class="flex-item"></div>
</div>

<button class="add">Add</button>
<button class="remove">Remove</button>

CSS

*, *:before, *:after {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  background: #666666;
  font-family: 'Ubuntu';
  font-size: 14px;
}

.flexbox {
  display: flex;
  flex-direction: row;

  border: 1px solid #000000;
}

.flex-item  {
  height: 100px;
  flex: 1;
  overflow: hidden;

  background: rgba(0, 0, 0, .3);
  border-left: 1px solid #000000;

  transition: all 500ms linear;
}
.flex-item:first-child {
  border-left: none;
}

.hover-collapse-item {
  white-space: nowrap;
  background: rgba(150, 0, 150, .3);
}
.flexbox:hover .hover-collapse-item {
  /* 0 does not work so we have to use a small number */
  flex: .00001;
}


.new-item {
  /* 0 does not work so we have to use a small number */
  /* Start our small */
  flex: .00001;

  background: rgba(0, 0, 0, .4);

  -webkit-animation: flexGrow 500ms ease forwards;
  -o-animation: flexGrow 500ms ease forwards;
  animation: flexGrow 500ms ease forwards;
}

.remove-item {
  flex: 1;

  -webkit-animation: flexShrink 500ms ease forwards;
  -o-animation: flexShrink 500ms ease forwards;
  animation: flexShrink 500ms ease forwards;
}

@-webkit-keyframes flexGrow {
  to {
    flex: 1;
  }
}
@-o-keyframes flexGrow {
  to {
    flex: 1;
  }
}
@keyframes flexGrow {
  to {
    flex: 1;
  }
}

@-webkit-keyframes flexShrink {
  to {
    flex: .01;
    flex: .00001;
  }
}
@-o-keyframes flexShrink {
  to {
    flex: .01;
    flex: .00001;
  }
}
@keyframes flexShrink {
  to {
    flex: .01;
    flex: .00001;
  }
}

JavaScript

$('.add').on('click', function() {
    $('.flexbox').append('<div class="flex-item new-item">' + lorem.ipsum('w4') + '</div>');    
});

$('.remove').on('click', function() {
    // Remove the last item in the list that isn't already being removed
   var $item = $('.flexbox .flex-item:not(.remove-item)').last();
    $item.addClass('remove-item');
    $item.on('animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd', function() {
        $item.remove();
    });
});