2

I'm trying to animate an element to full browser height when the user clicks on the top bar. The animation works, but once the (enter) animation is finished the container jumps back to zero height, while it's supposed to stay until the user clicks the close button.

How do I make the container stay 100vh when the animation is finished?

I tried adding height: 100vh; on the element, but by doing that the transition animation stopped working. (by removing the height, the animation works but the element disappears)

Not sure if it matters, but I changed v-if into v-show and also added a key on the container, but that didn't seem to make a difference.

Here's a link to my code. And to view the animation.

<!-- AboutMeComponent.vue -->
<template>
  <div>
    <div v-show="!extended" class="small-container" @click="extended = !extended">
      <h4>
        <a href="#">CLICK ME</a>
      </h4>
    </div>
    <ExtendTransition>
      <div v-show="extended" key="1" class="main-container">
        <div class="icon-container">
          <a v-show="extended" href="#" @click="extended = !extended">
            <font-awesome-icon icon="times"/>
          </a>
        </div>
      </div>
    </ExtendTransition>
  </div>
</template>
<!-- ExtendTransition.vue -->
<template>
  <transition appear name="extend" mode="out-in">
    <slot></slot>
  </transition>
</template>

<style lang="scss">
.extend-enter-active,
.extend-leave-active {
  transition: 3s;
}

.extend-enter-to,
.extend-leave {
  height: 100vh;
}

.extend-leave-to {
  height: calc(20px + 1vw);
}

.extend-enter {
  height: calc(40px + 3vw);
}
</style>
Sumurai8
  • 20,333
  • 11
  • 66
  • 100
Brammie
  • 23
  • 4
  • Hi there. I have taken the liberty of pulling the relevant code into the question, because questions in the format "why does x not work?" must always contain a [mcve] in the question. Please note that the code in this question is released under cc-by-sa (see footer), but since nothing special happens in this code, I doubt this is a problem. – Sumurai8 Jul 11 '19 at 09:51
  • @Sumurai8 ah right, thanks! – Brammie Jul 11 '19 at 10:03

1 Answers1

0

A transition only is applied while the transition is playing. Once the transition finished, all transition classes are removed. This means that your element must have the CSS you want it to have after the transition is finished. You can then use the transition classes to set the initial state and define the transition to get to that point, and from that point to the initial state.

The easiest way to solve this problem is by making ExtendTransition.vue the only component that worries about the transition, and using a wrapper that wraps the thing you want to extend.

<template>
  <transition appear name="extend" mode="out-in">
    <div class="extend-transition-wrapper" v-show="extended">
      <slot></slot>
    </div>
  </transition>
</template>

<script>
export default {
  props: {
    extended: {
      type: Boolean,
      default: false
    }
  }
};
</script>

The only thing you then have to do is to set the default state of your wrapper:

.extend-transition-wrapper {
  height: 100vh;
  will-change: height;
  position: relative;
}

In your ABoutMeComponent.vue you then use a prop to show and hide the content:

<ExtendTransition :extended="extended">
  <div class="main-container">
    <div class="icon-container">
      <a v-show="extended" href="#" @click="extended = !extended">
        <font-awesome-icon icon="times"/>
      </a>
    </div>
  </div>
</ExtendTransition>

And finally you set .main-container to always have a height of 100%. Since we set the wrapper to have position: relative, this will force the main container to become the height of that element.

Edit Vue Template

Sumurai8
  • 20,333
  • 11
  • 66
  • 100
  • Ah that makes a lot of sense! I've implemented it and it all works as intended now - thanks for your help! – Brammie Jul 11 '19 at 11:08