JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://unpkg.com/vue-smooth-height"></script>
<div id="app">
<h3>Vue smooth height</h3>
<p>When a change in data causes a change in height, vue smooth height will animate it for you.</p>
<div class="examples">
<div class="example">
<p>Without vue-smooth-height. Ew!</p>
<div class="container">
<div v-for="n in children" :key="n"></div>
</div>
</div>
<div class="example">
<p>With vue-smooth-height. Nice!</p>
<div class="container" ref="container">
<div v-for="n in children" :key="n"></div>
</div>
</div>
</div>
<h3>Transition compatibility</h3>
<div class="examples">
<div class="example example-2">
<p>Transitions on other properties will continue to work.</p>
<div class="container" :style="background">
<div v-for="n in children" :key="n"></div>
</div>
</div>
<div class="example example-5">
<p>Using a custom transition option.</p>
<div class="container">
<div v-for="n in children" :key="n"></div>
</div>
</div>
<div class="example example-6">
<p>Interrupted transitions are smooth.</p>
<div class="container">
<div v-for="n in children" :key="n"></div>
</div>
</div>
</div>
<h3>Conditional rendering and vue transitions on the smooth element</h3>
<div class="examples">
<div class="example example-7">
<p>Using v-if and <transition>.</p>
<transition name="fade">
<div v-if="children == childrenMax" class="container">
<div v-for="n in children" :key="n"></div>
</div>
</transition>
</div>
<div class="example example-8">
<p>Using v-show and <transition>.</p>
...
CSS
* {
box-sizing: border-box;
}
body {
background: #fefefe;
}
.examples {
display: flex;
flex-wrap: wrap;
}
.example {
margin-right: 30px;
margin-bottom: 30px;
height: 235px;
width: 250px;
}
.example > p {
min-height: 40px;
}
.container {
display: flex;
flex-wrap: wrap;
background: #BBDEFB;
overflow: hidden;
width: 166px;
padding: 2px;
will-change: height;
}
.container div {
background: #2196F3;
margin: 2px;
width: 50px;
height: 50px;
}
.list-container {
display: block;
width: 58px;
}
.example-nested-transition .container {
align-items: center;
justify-content: center;
}
.example-nested-transition .container div {
width: 125px;
height: 117px;
margin: 20px;
}
.example-2 .container {
transition: background 1s;
}
.example-3 .container, .example-4 .container {
overflow-y: auto;
}
.fade-enter-active, .fade-leave-active {
transition: opacity .85s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
.fade-fast-enter-active, .fade-fast-leave-active {
transition: opacity .5s;
}
.fade-fast-enter, .fade-fast-leave-to {
opacity: 0;
}
JavaScript
new Vue({
el:'#app',
mixins:[SmoothHeight],
data(){
return {
children: 3,
childrenMax: 9,
listChildren: 0,
listChildrenMax: 3,
direction: 'up',
count: 0,
}
},
computed: {
background() {
return {
background: this.count%2 == 0 ? '#BBDEFB' : '#263238'
}
}
},
mounted(){
let options = [
{ el: this.$refs.container },
{ el: '.example-2 .container' },
{ el: '.example-3 .container' },
{ el: '.example-4 .container', hideOverflow: true },
{ el: '.example-5 .container', transition: 'height 1s ease-in-out' },
{ el: '.example-6 .container', transition: 'height 4s' },
{ el: '.example-7 .container' },
{ el: '.example-8 .container' },
{ el: '.example-9 .container' },
{ el: '.example-10 .container' },
{ el: '.example-11 .container' },
]
this.$smoothElement(options)
setInterval(()=>{
this.children = this.count%2 == 0 ? this.childrenMax : 3
this.count++
if (this.direction === 'up') {
this.listChildren++
if (this.listChildren === this.listChildrenMax)
this.direction = 'down'
} else {
this.listChildren--
if (this.listChildren === 0)
this.direction = 'up'
}
},1250)
},
})