Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid parent element's height jumping when displaying a child div with v-if

I have a parent div and a child div. Child div is displayed via v-if. I can add a transition to the child element but once the transition is over the parent's height changes abruptly and it doesn't look nice.

I'd like something like the jQuery's slideToggle() function.

Here's my html where I'm using fade effect by transitioning the opacity:

  <div class="my-div">
    <p>some content</p>
    <transition name="fade" mode="out-in">
      <p key=1 v-if="show">hello</p>
    </transition>
  </div>

and here's the transition css:

.fade-enter-active,
.fade-leave-active {
  transition: opacity .5s
}

.fade-enter,
.fade-leave-to {
  opacity: 0
}

.my-div {
  background: lightgreen;
}

Here is the fiddle with my code:

https://jsfiddle.net/x15Lw6a3/

I don't know how to make the height transition. I've tried switching from opacity to height and to max-height as per some other questions but it just snaps up and down.

Any idea or a link to tutorial is appreciated. Thanks!

like image 551
brnd0 Avatar asked Oct 16 '22 07:10

brnd0


2 Answers

Try using max-height property by adding max-height: 100px; to fade-enter-active, .fade-leave-active rule and in .fade-enter, .fade-leave-to rule set it 0 as follows:

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#demo',
  data: {
    show: true
  }
})
.fade-enter-active,
.fade-leave-active {
  transition: all 0.5s ease;
  max-height: 100px;
  opacity: 1;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
  max-height: 0px;
}

.my-div {
  background: lightgreen;
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="demo">
  <button v-on:click="show = !show">
    Toggle
  </button>
  <div class="my-div">
  <p>some content</p>
  <transition name="fade" mode="out-in">
    <p key=1 v-if="show" >hello</p>
  </transition>
  </div>
</div>

Note:

You could see that the animation is not perfectly smooth

like image 64
Boussadjra Brahim Avatar answered Oct 21 '22 15:10

Boussadjra Brahim


Tried a number of approaches myself, ended up going for a component, and VueSlideToggle does the job perfectly for me. It makes use of CSS transition targeting the height property.

new Vue({
  el: '#demo',

  data() {
    return {
      show: true
    }
  }
});
.my-div {
  background: lightgreen;
}
<div id="demo">
  <button v-on:click="show = !show">Toggle</button>

  <div class="my-div">
    <p>some content</p>

    <vue-slide-toggle :open="show" tag="div" :duration="500">
      <p v-if="show">hello</p>
    </vue-slide-toggle>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-slide-toggle"></script>
like image 35
Yom T. Avatar answered Oct 21 '22 15:10

Yom T.