clankill3r
clankill3r

Reputation: 9583

Can I transition the flex-grow of a flex box to produce an animation?

Is it possible to transition the items in an flexbox? When you click I want all items to collapse except the one that is clicked. The one that is clicked should use all available space from the container.

// only works once!
$(".item").click(function() {
  $(".item").not(this).each(function() {
    $(this).addClass("collapse");
  });
});
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
}
.container {
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: auto;
  display: flex;
  flex-direction: column;
  height: 100%;
}
.item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: auto;
  transition: all 2s;
}
.collapse {
  flex-grow: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="item" style="background: red">a</div>
  <div class="item" style="background: green">b</div>
  <div class="item" style="background: blue">c</div>
  <div class="item" style="background: purple">d</div>
</div>

JSFiddle: http://jsfiddle.net/clankill3r/L8hktsgn/

Upvotes: 41

Views: 107616

Answers (4)

John Balvin Arias
John Balvin Arias

Reputation: 2896

If you want only one row this could work https://codepen.io/balvin/pen/gKrXdM but if you want to wrap them you could use https://codepen.io/balvin/pen/wXGyYw Seems that it's a hack, but setting width:0;flex-grow:1 it's the solution, but in order to wrap the elements, you need to explicity tell width to the browser, because it does not know at which width you want the elemements to wrap, and with that in mind you just play with setTimeout. Check the codes

Upvotes: 2

Hashem Qolami
Hashem Qolami

Reputation: 99554

flex-grow is animatable but only if the value is a <number>. However it seems that Google Chrome (v41) doesn't trigger the animation if the value is set to 0.

A workaround for this could be to use a very small value instead — something like 0.0001:

Updated example.

$(".item").click(function() {
    $(".item").addClass("collapse");
    $(this).removeClass("collapse");    
});
html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;    
}

.container {
    flex-basis: auto;
    display: flex;
    flex-direction: column;
    height: 100%;
}

.item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: auto;
    transition: all 2s;
}

.collapse {
    flex-grow: 0.001;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
    <div class="item" style="background: red">a</div>
    <div class="item" style="background: green">b</div>
    <div class="item" style="background: blue">c</div>
    <div class="item" style="background: purple">d</div>
</div>

Upvotes: 49

Ashot Khanamiryan
Ashot Khanamiryan

Reputation: 1134

$(".item").click(function() {
    $(this).removeClass('collapse');
    $(".item").not(this).each(function() {
        $(this).addClass("collapse");    
    });


});

and you can animate flex-grow from 20 to 1

.item {
    flex-grow: 20;
    transition: all 1s;
}

.collapse {
    flex-grow: 1;

}

http://jsfiddle.net/L8hktsgn/11/

Upvotes: 5

Jonathan
Jonathan

Reputation: 3644

You can work with max-height.

.item
{
  max-height:100%;
}

.collapse
{
  max-height: 64px;
}

http://jsfiddle.net/L8hktsgn/9/

Upvotes: 1

Related Questions