Every once in a while I run across some tools that I can’t develop without. VueJS (Vue.js) is definitely hands down the best front end Javascript framework out there. It’s easy to use, extend, and customize to what you need it to do. The front end of this tutorial series is written in VueJS and at 521 Dimensions and we use VueJS daily in our app development process. One of the most awesome feature of Vue is their transitions. It makes animating a process a breeze!

For a good front end framework to really show it’s power, it has to not only function well, but also look good. This requires knowledge of CSS and really tricky CSS such as animations. Animations add that extra UX flare to a project that make it stand out above the rest. I myself am not too great with CSS. I write it, it works, but some of the features I just feel like I’m missing something. This is especially true when building animations in CSS. That’s where the tool of Animista (Animista) comes in. It’s built by [Ana Travas](Ana Travas (@ana108) | Twitter and is a set of on-demand animations. You essentially can test CSS animations, customize them, then download the keyframes and CSS classes needed for your application. It’s simply amazing!

The best features about VueJS and Animista? They work extremely well together. VueJS has awesome transitions functionality built right into the framework: Enter/Leave & List Transitions — Vue.js. You can take this functionality and extend it easily to use animations from Animista. Let’s get started!

What We Will Build

For the sake of this tutorial, we will build a slide out menu similar to what is found on Roast when the ‘Filters’ button is clicked. It’s a great example and is very easy to implement in your own application.

Step 1: Build Slide Out Menu Component

The first step is to build our slide out menu component. This will be a Vue Component (Components Basics — Vue.js that slides out from the left side of the screen.

The initial component will look like:

<style lang="scss">
  div.filters-container{
    background-color: white;
    position: fixed;
    left: 0;
    bottom: 0;
    top: 75px;
    max-width: 550px;
    width: 100%;
    padding-top: 50px;
    box-shadow: 0 2px 4px 0 rgba(3,27,78,0.10);
    z-index: 99;

}
</style>

<template>
  <div class="filters-container" v-show="showFilters">

  </div>
</template>

<script>
  import { EventBus } from '/path/to/event-bus.js';

  export default {

    data(){
      return {
        showFilters: false
      }
    },


    mounted(){
      EventBus.$on('show-filters', function(){
        this.showFilters = true;
      }.bind(this));

        EventBus.$on('hide-filters', function(){
        this.showFilters = false;
      }.bind(this));
    }
  }
</script>

First thing to note, I’m using SASS for this tutorial. You don’t have to use SASS you can use straight up CSS if that is what works for your project.

In the styles, I have this as a fixed element that maxes out at 550px. I have the width set to 100% so on a mobile device, it goes full screen.

Next, I have the component shown off of a data variable named ‘showFilters’. This is a boolean set to true or false. If it is true, then the component will be shown, if it is false, then the component will be hidden. We will want this to animate, and I will explain how shortly.

Lastly, I have the shown variable updated by an event. I created an event bus per this guide for Vue 2.0: Migration from Vuex 0.6.x to 1.0 — Vue.js. When shown or hidden, the event bus will fire and we will show or hide the filters. You can do this functionality in a variety of ways, you just need a way to toggle whether or not the filter is shown or hidden.

Step 2: Download Slide-In-Left animation from Animista.net

If you visit Animista you will see there are TONS of animations. You can animate in so many different ways. In this use case, we just want a simple slide in left animation from our menu. To download that animation, visit: Animista Slide In Left. Here you can customize duration, delay, timing function, etc. It’s so quick to use!

Once you have it customized to your heart’s content, you can now download the CSS classes and keyframes. To do that, click the ‘Generate Code’ brackets icon in the top right of the animation window. You will see two chunks of code you need to copy.

The first one will be the class. This is highly important as it’s what Vue uses to identify the animation to use. In our use case, it should look like:

.slide-in-left {
    -webkit-animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
            animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}

The next chunk of code is equally important and is key frames for the ‘slide-in-left’ class:

/* ----------------------------------------------
 * Generated by Animista on 2018-5-16 13:50:1
 * w: http://animista.net, t: @cssanimista
 * ---------------------------------------------- */

/**
 * ----------------------------------------
 * animation slide-in-left
 * ----------------------------------------
 */
@-webkit-keyframes slide-in-left {
  0% {
    -webkit-transform: translateX(-1000px);
            transform: translateX(-1000px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0);
            transform: translateX(0);
    opacity: 1;
  }
}
@keyframes slide-in-left {
  0% {
    -webkit-transform: translateX(-1000px);
            transform: translateX(-1000px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0);
            transform: translateX(0);
    opacity: 1;
  }
}

There are a couple things you can do with this code.

  1. You could place it all in your Vue Component. This is useful if you have an animation that is ONLY being used within that component. However, most of the time animations are re-usable.
  2. If you are using standard CSS, copy both of these chunks of code to your file. You will be able to reference them as needed.
  3. If you are using SASS, like in this example, I created an animations folder and placed the css and keyframes in a file named: _slide-in-left.scss. This gets compiled in my main SASS file and can be reused throughout components.

Now that you have your animations, let’s make that slide out navigation work!

Step 3: Wrap Vue Component in <transition> Tag

So to make sure Vue adds the proper animations and reverses animations when needed, you need to wrap your entire Vue component in a <transition> tag. This allows you to utilize your CSS animation on a component. Now Vue will automatically add the classes necessary to get your component to animate. This is actually a super slick feature of Vue transitions. You can animate entrances and exits and Vue will take care of it for you! For more information on transition statuses check out: Enter/Leave & List Transitions — Vue.js.

Our component should now look like:

<style lang="scss">
  div.filters-container{
    background-color: white;
    position: fixed;
    left: 0;
    bottom: 0;
    top: 75px;
    max-width: 550px;
    width: 100%;
    padding-top: 50px;
    box-shadow: 0 2px 4px 0 rgba(3,27,78,0.10);
    z-index: 99;

}
</style>

<template>
  <transition name="slide-in-left">
    <div class="filters-container" v-show="showFilters">

    </div>
  </transition>
</template>

<script>
  export default {

    data(){
      return {
        showFilters: false
      }
    },


    mounted(){
      EventBus.$on('show-filters', function(){
        this.showFilters = true;
      }.bind(this));

        EventBus.$on('hide-filters', function(){
        this.showFilters = false;
      }.bind(this));
    }
  }
</script>

The big thing to note, besides the entire component in a <transition> tag is the name attribute on the <transition> tag. This is huge. This references the class that will be used to do the animation. In this case it is set to slide-in-left. If you see in Step 2, the CSS class was slide-in-left. This is how Vue knows which transition to use. There’s really only one more step and we are ready done!

Step 4: Adjust CSS Classes for Animation to work with VueJS

This is really the meat of getting everything working together. I mentioned earlier that Vue adds custom transition statuses to the element to make sure it is firing correctly. To make use of these open the file that contains your animation and find the class. Update your class to be:

.slide-in-left-enter-active {
    -webkit-animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
            animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}

VueJS will add the enter-active suffix to your class when you are starting to run the transition. This gets fired when your variable that determines whether or not to show the navigation.

Next, after that class add the following class:

.slide-in-left-leave-active{
  -webkit-animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both reverse;
          animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both reverse;
}

What this does is the same animation when the navigation is transitioning to hidden. Looks exactly the same EXCEPT for the reverse style on the property. This is so the animation runs in reverse when hidden! Slick isn’t it? Now that you have these properties defined, and your component wrapped in a transition tag, you are ready to use your animation!

Our final CSS should look like:

.slide-in-left-enter-active {
    -webkit-animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
            animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}

.slide-in-left-leave-active{
  -webkit-animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both reverse;
          animation: slide-in-left 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both reverse;
}

/* ----------------------------------------------
 * Generated by Animista on 2018-4-12 13:38:23
 * w: http://animista.net, t: @cssanimista
 * ---------------------------------------------- */

/**
 * ----------------------------------------
 * animation slide-in-left
 * ----------------------------------------
 */
@-webkit-keyframes slide-in-left {
  0% {
    -webkit-transform: translateX(-1000px);
            transform: translateX(-1000px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0);
            transform: translateX(0);
    opacity: 1;
  }
}
@keyframes slide-in-left {
  0% {
    -webkit-transform: translateX(-1000px);
            transform: translateX(-1000px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0);
            transform: translateX(0);
    opacity: 1;
  }
}

And our Vue Component should look like:

<style lang="scss">
  div.filters-container{
    background-color: white;
    position: fixed;
    left: 0;
    bottom: 0;
    top: 75px;
    max-width: 550px;
    width: 100%;
    padding-top: 50px;
    box-shadow: 0 2px 4px 0 rgba(3,27,78,0.10);
    z-index: 99;

}
</style>

<template>
  <transition name="slide-in-left">
    <div class="filters-container" v-show="showFilters">

    </div>
  </transition>
</template>

<script>
  export default {

    data(){
      return {
        showFilters: false
      }
    },


    mounted(){
      EventBus.$on('show-filters', function(){
        this.showFilters = true;
      }.bind(this));

        EventBus.$on('hide-filters', function(){
        this.showFilters = false;
      }.bind(this));
    }
  }
</script>

Conclusion

The combination of VueJS and Animista helps make slick front end development a breeze! You can add multiple animations to a project to be used in a variety of scenarios and just map the animated/transitioning object in a transition tag that references the class name of your transition. Bam! UX transition ready to rock! Just make sure you add the corresponding exit class and suffix of leave-active IF that’s what you want to use.

To check out how I’ve used a few more transitions, and this transition in Roast, visit: Roast and Brew Github. Of course, ask any questions in the comments below! If you want to learn more and take a deeper dive into API Driven Development, sign up for the mailing list: API Driven Development Mailing List. We will be launching exclusive intro offer soon!