Transitions in Vue

For one of our clients, we developed a webshop in which the product configurator is one of the most important parts. The products have a lot of specifications (e.g. color and size) that customers may configure. For a user-friendly experience, the different specifications are listed in blocks below each other. One block at a time is expanded so that the customer can focus on choosing the right option for each of the specifications. This way, the customer can completely configure the product.

The first version of this product configurator was written in plain javascript and jQuery. Although this was working well, the requirements were changing over time. We needed more flexibility, which wasn’t possible in the first version. Therefore, we decided to rewrite the configurator with the new set of requirements in mind.

Meanwhile, Vue.js has become very popular. We used it ourselves in some of our other projects and also for the product configurator it seemed the perfect tool. With Vue we have the flexibility we need to fulfill all requirements. In this blog, we describe our experiences with Vue transitions for this specific case.

Setup

One thing the old configurator doesn’t have, is transitions. We start with a simple setup in Vue to incorporate them. We create a list of blocks below each other, and each block should be able to expand and collapse via a nice transition. We first show the final result and then discuss some parts in more detail.

Single element transition

For animating a single block, we used a ‘single element transition‘ (code not necessary for the transition is not shown):

Single transition sample code

Click to view large version

We will discuss some features of this simple single element transition:

When clicking the button, the property ‘show’ will switch from true to false or vice versa and triggers the transition. We transition both the height and opacity of the block.

Transition name and classes

The element to be transitioned is placed within a <transition> tag, which has a name attribute (‘fade’ in this example). One of the advantages of adding a name attribute, is that several (css) classes are automatically applied to the transition. You can use them in the styles section of your component to describe the behaviour of the transition.

The following classes are generated by default:

  • v-enter: where ‘v’ should be replaced by the name of the transition. In this case, the class name would be .fade-enter. It defines the state of the element when it enters.
  • v-enter-active, in which you can specify the duration, delay and easing curve for the transition
  • v-enter-to, which defines the ending state
  • Similar for elements that enter, there are classes for leaving elements: v-leave, v-leave-active, v-leave-to.

For clarity, we include the schematic picture of a transition from the Vue.js documentation, because this perfectly illustrates the different phases of the transition in our example. The v-enter-to and v-leave states are identical, which results in identical css specifications for the corresponding classes. The same is true for the v-enter and v-leave-to states.

Vue transition classes

Transitioning height

In our case, we wanted to transition the height of a block and ran into some difficulties.

In the initial setup (not shown in this blog), the transition was smooth until the block almost disappeared. At that point, the blocks below the transitioned one shifted up with a little jump. It turned out that the margin we added to the <p> element (containing the text ‘Block 2’) for better positioning within its container was responsible for this jump. The margin of this element was extending beyond the border of the block.

Transition blocks with margin

What happens is when you transition the height of an element, margins on this element are not transitioned. At the moment the transitions ends, the element is removed from the DOM or hidden using display:none (depending on whether you use v-if or v-show). Then, the margins also disappear instantly and you see a little jump. The transition therefore looks great until the moment it ends.

We avoided this behaviour by using a wrapper element directly within the <transition> tag and made sure it had no margins or children with margins extending beyond this wrapper.

Last, keep in mind to transition the max-height property instead of the height in the styles part. In addition, it might be needed to add an overflow:hidden to the transition wrapper to avoid elements from (visually) floating through each other.

Transitions in lists

For our product configurator, we needed an additional feature. Sometimes, additional specification blocks where needed depending on choices made by the user.

To make this work, we listed all blocks in a <transition-group>, while specifying the content of the blocks and their visibility in the data object. To add an extra block, we simply modified the data object by toggling the visibility of the block to be shown. By default, adding blocks this way doesn’t look very nice, because the blocks are moving abrupt.

There is an easy way to solve this though:

  • give the <transition-group> a name attribute
  • add .v-move {transition: transform 1s;} to the styles section, where ‘v’ is replaced by the name of the transition group

This will create nice and smooth transitions. However, this will only work when the list contents are modified through the data object. It will have no effect when a list item is made visible/invisible using a v-show or v-if.

Concluding remarks

In this blog, we described a use case for Vue transitions which we encountered when developing a product configurator for a webshop. We ran into some practical issues for this specific situation, found a solution for these issues and we would like to share this.

A more complete overview of features and possibilities related to transitions in Vue can be found in the official documentation.


Mijn Twitter profiel Mijn Facebook profiel
Leonie Derendorp Webdeveloper and co-owner of PLint-sites in Sittard, The Netherlands. I love to create complex webapplications using Laravel! Latest post
Customizing emails in Laravel

Leave a Reply

Your email address will not be published. Required fields are marked *