search
HomeWeb Front-endCSS TutorialThe Power of Named Transitions in Vue

The Power of Named Transitions in Vue

Vue.js provides a variety of ways to control how elements or components are visually rendered when inserted into DOM, such as fading in, sliding in, or other visual effects. Almost all of these features are based on a single component: the transition component .

A simple example is v-if based on a boolean value. When the Boolean is true, the element appears; when it is false, the element disappears. Usually, this element appears and disappears suddenly, but with the transition component, you can control the visual effects.

<transition><div v-if="isVisible"> Is it visible?</div></transition>

Many articles provide a good introduction to transition components, such as those of Sarah Drasner, Nicolas Udy, and Hassan Djirdeh. Each article details different aspects of the Vue transition component. This article will focus on one aspect of transition components: they can be "named".

<transition name="fade"><div v-if="isVisible"> Is it visible?</div></transition>

The initial change brought about by this property is that the CSS class injected into an element during the transition sequence will be prefixed with the given name. Basically, it will be fade-enter instead of v-enter above. This single property has much more than this simple option. It can be used to take advantage of certain features of Vue and CSS to produce some interesting results.

Another thing to consider is that the name attribute can be bound:

<transition :name="currentTransition"><div v-if="isVisible"> Is it visible?</div></transition>

In this example, the transition will be named as the value parsed to by currentTransition . This simple change provides another layer of options and functionality for the application's animation. Using static and dynamic naming transitions, projects can have a series of pre-built transitions ready to be applied throughout the application, can extend the components applied to their existing transitions, switch transitions used before or after the application, allow users to select transitions, and control how individual elements of the list transition into place based on the current state of the list.

This article aims to explore these features and explain how to use them.

What happens when naming transitions?

By default, when using the transition component, it applies specific classes to elements in a specific order. These classes can be used in CSS. Without CSS, these classes actually have no effect on the elements. Therefore, CSS of this nature is needed:

 .v-enter,
.v-leave-to {
  opacity: 0;
}

.v-enter-active,
.v-leave-active {
  transition: 0.5s;
}

This causes the element to fade in and out for a duration of half a second. The slight changes to the transition provide users with elegant visual feedback. However, there is still a problem to consider. But first, what is the difference between naming transitions?

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

.fade-enter-active,
.fade-leave-active {
  transition: 0.5s;
}

Basically the same CSS, but using fade- as prefix instead of v- . This naming resolves issues that may occur when using the default class name of the transition component. v- prefix actually makes the class global, especially when placing CSS in a style block at the application root level. This will actually make the *all* transitions without the name attribute in the entire application use the same transition effect. For smaller applications, this may be enough, but in larger, more complex applications, this can lead to bad visuals, as not everything should fade in and out in half a second.

The naming transition provides developers with levels of control throughout their project on how to visually insert or delete different elements or components. It is recommended that all transitions be named – even if only one – to develop the habit of doing so. Even if the application has only one transition effect, a new transition effect may need to be added in the future. The existing transitions have been named in the project, which simplifies the effort to add new transitions.

Build a set of transition effects

Naming transitions provide a simple but very useful process. A common practice might be to create transition classes as part of the components that use them. If another common practice of scoped component styles is completed, these classes will only be available for that particular component. If two different components have similar transitions in their style blocks, then we are just repeating the code.

So let's consider keeping the transitional CSS in the style block of the application root directory, usually app.vue file. In most of my projects, I put them in the last part of the style block for easy searching for adjustment and addition. Save CSS in this location so that the transition effect can be used for every use of the transition component throughout the application. Here are some examples from some of my projects.

 .fade-enter,
.fade-leave-to { opacity: 0; }
.fade-enter-active,
.fade-leave-active { transition: 0.5s; }

.slide-enter {
  opacity: 0;
  transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0);
}

.slide-enter-to { transform: scale3d(1, 1, 1); }
.slide-enter-active,
.slide-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); }
.slide-leave { transform: scale3d(1, 1, 1); }

.slide-leave-to {
  opacity: 0;
  transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0);
}

.rotate-enter { transform: perspective(500px) rotate3d(0, 1, 0, 90deg); }
.rotate-enter-active,
.rotate-leave-active { transition: 0.5s; }
.rotate-leave-to { transform: perspective(500px) rotate3d(0, 1, 0, -90deg); }

Depending on your preferences and project needs, there are several ways to store these transition classes. The first one, as mentioned earlier, is to save everything in the style block of the app.vue file. You can also save all transitioned Sass parts of the project in the assets folder of the project and import it into the style block of the application.

 @import "assets/_transitions.scss";

This method allows for tweaking and adding transition collections outside of Vue files. Another benefit of this setup is that if the project shares transition effects, you can easily transfer such files between projects. If a project gets a new transition, it is easy to transfer the added content to another project without touching the main project file.

If you are using CSS instead of Sass, you can include the file as a dependency for your project. You can do this by saving the file in the assets folder of your project and placing a require statement in the main.js file.

 require("@/assets/transitions.css");

Another option is to save the transition style in a static CSS file, which can be stored elsewhere, either in the public folder of the project, or directly on the server. Since this is a regular CSS file, there is no need to build or deploy - just include a link reference in the index.html file.

<link href="/css/transitions.css" rel="stylesheet" type="text/css">

This file can also be potentially stored in a CDN for sharing all projects. Whenever the file is updated, the changes are immediately available in all places where it is referenced. If a new transition name is created, the existing project can start using a new name as needed.

Now, let's slow down for a minute

When we build a transition collection to use throughout our project, let's consider users who may not want the animation to be too sudden or do not want the animation to appear at all. Some may think our animations are too exaggerated and unnecessary, but for some, they can actually cause problems. Some time ago, WebKit introduced prefers-reduced-motion media queries to help solve possible vestibular spectrum barriers . Eric Bailey also posted a good introduction to media queries.

In most cases, it is very easy to have media queries as part of our transition set and should be considered. We can reduce the amount of exercise involved in the transition to reduce the negative impact, or simply turn them off.

Here is a simple example from one of my demos:

 .next-enter {
  opacity: 0;
  transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0);
}

.next-enter-to { transform: scale3d(1, 1, 1); }
.next-enter-active,
.next-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); }
.next-leave { transform: scale3d(1, 1, 1); }

.next-leave-to {
  opacity: 0;
  transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0);
}

/* Use simpler transitions if animation is reduced at the operating system level*/
@media screen and (prefers-reduced-motion: reduce) {
  .next-enter {
    opacity: 0;
    transform: translate3d(100px, 0, 0);
  }

  .next-enter-active,
  .next-leave-active { transition: 0.5s; }

  .next-leave-to {
    opacity: 0;
    transform: translate3d(-100px, 0, 0);
  }
}

In this example, I took a rather exaggerated transition and made it simpler. Animation is a sliding animation that moves to the left with a elastic easing effect, then shrinks and fades out when removed. If someone's reduced motion preference is set, the animation becomes a simpler transition, with a shorter distance (which makes it slower) and keeps fade out. If we want to turn them off, we just need to refer to the class with the transition attribute and set their values ​​to none .

To test this, you need to find and select a check box on your respective operating systems. On Windows, you can find it in<kbd>控制面板> 易于访问中心> 使计算机更容易查看</kbd>; look for "Close all unnecessary animations (if possible).". On a Mac, check<kbd>系统偏好设置> 辅助功能> 显示</kbd>; find "Reduce Sports". The latest iOS devices have similar settings under<kbd>辅助功能</kbd>.

Let's keep the transition sets flexible

With this transition set, there may be problems with inflexibility. For example, what if an element needs a slightly slower fading time? Assuming everything else in the effect can be left unchanged, just change transition-duration . There are ways to adjust without creating a completely new transition name.

The easiest way is to use inline styles directly on elements within the transition component.

<transition name="fade"><div style="transition-duration: 6s;" v-if="isVisible"> This has different durations</div></transition>

Such changes can be done through various methods of handling styles and classes provided by Vue.

Suppose you are using component elements with is attribute to perform dynamic components, for example:

<transition mode="out-in" name="fade"><component :is="currentComponent"></component></transition>

Even with this dynamic component, we have options to adjust the properties of the transition effect. Similarly, we can apply an inline style on the component element, which will be placed on the component's root element. The root element also receives transition classes, so we will directly override its properties.

<transition mode="out-in" name="fade"><component :is="currentComponent" style="transition-duration: 6s;"></component></transition>

Another option is to pass the props to our components. This way, the changes it needs can be applied to its root element through the component's code.

<transition mode="out-in" name="fade"><component :is="currentComponent" duration="6s"></component></transition>
<template><div :style="`transition-duration: ${duration}`"> Component One</div></template>
<script>
export default {
  name: "component-one",
  props: {
    duration: String
  }
};
</script>

We can also override the properties of transition classes inside component style blocks, especially when within their scope.

 .fade-enter-active,
.fade-leave-active { transition-duration: 1s; }

In this case, the component's fade-out duration will be one second, rather than the global duration of half a second. We can even go a step further and set different durations for each side of the sequence.

 .fade-enter-active { transition-duration: 1s; }
.fade-leave-active { transition-duration: 2s; }

Any global transition class can be changed within the component as needed. While this is not as flexible as changing properties outside of class structure, it is still very useful in some cases.

As you can see, even with our prebuilt transition collection, we still have the option to be flexible.

Dynamic transition

Even after we can do all this interesting things with Vue's transition component, another interesting feature is still waiting to be explored. The name property on the transition component can be dynamic, meaning we can change the transition currently in use at will.

This means that transitions can be changed according to different situations in the code to have different animation effects. For example, we can change the transition based on the answers to the question, decide on the transition based on user interaction, and have the list use different transitions based on the current state of the list itself.

Let's look at these three examples.

Example 1: Change the transition according to the answer

In this example, we have a simple math problem to answer. Choose two numbers randomly and we should provide the sum of them. Then click the button to compare the answer to the expected answer. A small notification will appear above the equation indicating whether the answer is true or false. If the answer is correct, the notification provides a suggestion nodding to indicate a positive transition of the up and down animation. If your answer is incorrect, the notification will move left and right, indicating a shaking of your head and negation.

The logic behind it is not complicated, and the setting of transition is not complicated. This is HTML:

<transition :name="currentTransition"><div v-if="answerChecked"> {{ response }}</div></transition>

The nature is quite simple. We have a bound name on the transition and then a v-if on the notification div. We also applied a true or false class to decorate notifications based on responses.

Here is the transitional CSS:

 .positive-enter-active { animation: positive 1s; }
@keyframes positive {
  0% { transform: translate3d(0, 0, 0); }
  25% { transform: translate3d(0, -20px, 0); }
  50% { transform: translate3d(0, 20px, 0); }
  75% { transform: translate3d(0, -20px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

.negative-enter-active { animation: negative 1s; }
@keyframes negative {
  0% { transform: translate3d(0, 0, 0); }
  25% { transform: translate3d(-20px, 0, 0); }
  50% { transform: translate3d(20px, 0, 0); }
  75% { transform: translate3d(-20px, 0, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

You will see that I'm using CSS animations to achieve up and down and left and right effects.

Here is some JavaScript code:

 methods: {
  randomProblem: function () {
    this.a = Math.floor(Math.random() * Math.floor(10));
    this.b = Math.floor(Math.random() * Math.floor(10));
  },
  check: function () {
    this.response = this.a this.b === parseInt(this.answer);
    this.answerChecked = true;
    this.currentTransition = this.response ? 'positive' : 'negative';
  },
  reset: function () {
    this.answer = null;
    this.answerChecked = false;
    this.randomProblem();
  }
}

Here is the randomProblem method to set our equation. The check method determines which transition effect to use based on comparing the provided answer with the correct answer. Then there is the simple reset method, which just resets everything.

This is just a simple example. Another possible example is a notification with two different effects depending on whether the notification is important or not. If the message is not very important, then we can use a subtle animation that will not let the user's eyes leave the current task. If it matters, we can use more direct animations to force the eye to look up notifications.

Example 2: Change the transition based on user interaction

Another thing we can build is some sort of carousel. This could be a slide presentation, a picture gallery, or a series of instructions. The basic idea is that we need to present information to users in order. In this demonstration, the user can decide when to continue and whether to move forward or backward.

This is also a fairly simple setup. This example is more or less a slide presentation type case. The two buttons at the bottom toggle between two components with sliding transitions. A real project will have more components, or may change the logic of component content, depending on the current slide. This example will be kept simple to demonstrate the idea.

This is HTML:

<transition :name="currentTransition" mode="out-in"><component :is="slides[currentSlide]"></component></transition>

You will see that whenever the component is switched through the binding is attribute on the component element, we just make the transition.

This is CSS:

 .next-enter {
  opacity: 0;
  transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0);
}

.next-enter-to { transform: scale3d(1, 1, 1); }
.next-enter-active,
.next-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); }
.next-leave { transform: scale3d(1, 1, 1); }

.next-leave-to {
  opacity: 0;
  transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0);
}

.prev-enter {
  opacity: 0;
  transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0);
}

.prev-enter-to { transform: scale3d(1, 1, 1); }
.prev-enter-active,
.prev-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); }
.prev-leave { transform: scale3d(1, 1, 1); }

.prev-leave-to {
  opacity: 0;
  transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0);
}

/* Use simpler transitions if animation is reduced at the operating system level*/
@media screen and (prefers-reduced-motion: reduce) {
  .next-enter { opacity: 0; transform: translate3d(100px, 0, 0); }
  .next-enter-active,
  .next-leave-active { transition: 0.5s; }
  .next-leave-to { opacity: 0; transform: translate3d(-100px, 0, 0); }

  .prev-enter { opacity: 0; transform: translate3d(-100px, 0, 0); }
  .prev-enter-active,
  .prev-leave-active { transition: 0.5s; }
  .prev-leave-to { opacity: 0; transform: translate3d(100px, 0, 0); }
}

Here we have two transitions, one for the "next" button when the user clicks the "next" button and the other for the "prev" button. Each basically uses transform property to slide the component in the appropriate direction, but there is some extra to create a squeezing effect for a cartoon effect. We also use prefers-reduced-motion to change the animation to a simpler fade effect and swipe it a little in the proper direction.

Now, for JavaScript:

 methods: {
  changeSlide: function (dir) {
    this.currentSlide = dir === 'next' ? this.currentSlide 1 : this.currentSlide - 1;
    this.currentTransition = dir;
  }
}

Each button calls the changeSlide method on its click event and passes the direction it represents. Then we have some logic to track what the current slide is. Single-line code controls which transition to use. Since the "next" button passes "next" as the direction, it corresponds to the "next" transition in CSS. The same is true for the "prev" button. Each time the user clicks a button, the application automatically knows which transition to use. Therefore, we have a good transition effect that can provide context about the direction the user is heading in the sequence.

Example 3: Change the transition based on list status

For our last example, we will learn how to change the transition based on the current state of the list within transition-group component. The idea here is a list, each time an item is updated, each time using a different transition.

In this example, we show the city list on the right and the blank list on the left. When selecting cities on the right, they fill in the blanks on the left. The first city slides in from above while fading into the view. The next city before the last city will slide in from the right or left, depending on the previous transition, the last city will slide in from below.

This is HTML:

<transition-group :name="currentListTransition" tag="ul"><li :key="item" v-for="(item, index) in selectedItems"> {{ item }}</li></transition-group>

As usual, a fairly simple setup. Here are the transitions in CSS:

 .top-enter-active,
.top-leave-active { transition: 0.5s; }
.top-enter,
.top-leave-to {
  opacity: 0;
  transform: translate3d(0, -40px, 0);
}

.top-move {
  opacity: 0.5;
  transition: 0.5s;
}

.left-enter-active,
.left-leave-active { transition: 0.5s; }
.left-enter,
.left-leave-to {
  opacity: 0;
  transform: translate3d(-40px, 0, 0);
}

.left-move {
  opacity: 0.5;
  transition: 0.5s;
}

.right-enter-active,
.right-leave-active { transition: 0.5s; }
.right-enter,
.right-leave-to {
  opacity: 0;
  transform: translate3d(40px, 0, 0);
}

.right-move {
  opacity: 0.5;
  transition: 0.5s;
}

.bottom-enter-active,
.bottom-leave-active { transition: 0.5s; }
.bottom-enter,
.bottom-leave-to {
  opacity: 0;
  transform: translate3d(0, 30px, 0);
}

.bottom-move {
  opacity: 0.5;
  transition: 0.5s;
}

/* If animation is reduced at the operating system level, close the transition*/
@media screen and (prefers-reduced-motion: reduce) {
  .top-enter-active,
  .top-leave-active { transition: none; }
  .top-move { transition: none; }
  .left-enter-active,
  .left-leave-active { transition: none; }
  .left-move { transition: none; }
  .right-enter-active,
  .right-leave-active { transition: none; }
  .right-move { transition: none; }
  .bottom-enter-active,
  .bottom-leave-active { transition: none; }
  .bottom-move { transition: none; }
}

As you can see, each possible city direction appears in the blank list with a transition.

Now, for our JavaScript:

 methods: {
  chooseCity: function (index) {
    let selectedLength = this.selectedItems.length;
    let citiesLength = this.cities.length;
    let clt = this.currentListTransition;

    if (selectedLength === 0) {
      clt = 'top';
    } else if (selectedLength > 0 && selectedLength <p> The <code>chooseCity</code> method handles what happens when selecting each city. What we are mainly concerned with is a series of <code>if</code> and <code>if/else</code> statements in the middle of the method. When a city is selected, the logic looks at the current length of the <code>selectedItems</code> array that ends up pushing the selected city into. If the length is zero, then that is the first city, so the transition should make it enter from the top. If the length is between zero and the total number of city lists, the transition should be right or left. The new direction used is based on the direction of the previous transition direction. Then, finally, if we select the last city, it will change to the bottom transition. Again, we use <code>prefers-reduced-motion</code> , which completely closes the transition in this case.</p><p> Another option to change the list transition is to make changes based on the type of the selected item; for example, East Coast and West Coast cities, each city has a different transition. Consider changing the transition based on the current number of items added to the list; for example, a different transition for every five items.</p><h3 id="Goodbye-thanks-for-all-the-transitions"> Goodbye, thanks for all the transitions</h3><p> After all these examples and ideas, I hope you will consider taking advantage of Vue's transition component in your own project. Explore the possibilities of adding transitions and animations to your app to provide context and interests to your users. In many cases, such additions are very easy to implement, almost to the point where it is a pity not to add them. Vue provides an exciting and very useful out-of-the-box feature, the transition component, which I can only encourage.</p><p> cheers.</p>

The above is the detailed content of The Power of Named Transitions in Vue. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Next Level CSS Styling for CursorsNext Level CSS Styling for CursorsApr 23, 2025 am 11:04 AM

Custom cursors with CSS are great, but we can take things to the next level with JavaScript. Using JavaScript, we can transition between cursor states, place dynamic text within the cursor, apply complex animations, and apply filters.

Worlds Collide: Keyframe Collision Detection Using Style QueriesWorlds Collide: Keyframe Collision Detection Using Style QueriesApr 23, 2025 am 10:42 AM

Interactive CSS animations with elements ricocheting off each other seem more plausible in 2025. While it’s unnecessary to implement Pong in CSS, the increasing flexibility and power of CSS reinforce Lee's suspicion that one day it will be a

Using CSS backdrop-filter for UI EffectsUsing CSS backdrop-filter for UI EffectsApr 23, 2025 am 10:20 AM

Tips and tricks on utilizing the CSS backdrop-filter property to style user interfaces. You’ll learn how to layer backdrop filters among multiple elements, and integrate them with other CSS graphical effects to create elaborate designs.

SMIL on?SMIL on?Apr 23, 2025 am 09:57 AM

Well, it turns out that SVG's built-in animation features were never deprecated as planned. Sure, CSS and JavaScript are more than capable of carrying the load, but it's good to know that SMIL is not dead in the water as previously

'Pretty' is in the eye of the beholder'Pretty' is in the eye of the beholderApr 23, 2025 am 09:40 AM

Yay, let's jump for text-wrap: pretty landing in Safari Technology Preview! But beware that it's different from how it works in Chromium browsers.

CSS-Tricks Chronicles XLIIICSS-Tricks Chronicles XLIIIApr 23, 2025 am 09:35 AM

This CSS-Tricks update highlights significant progress in the Almanac, recent podcast appearances, a new CSS counters guide, and the addition of several new authors contributing valuable content.

Tailwind's @apply Feature is Better Than it SoundsTailwind's @apply Feature is Better Than it SoundsApr 23, 2025 am 09:23 AM

Most of the time, people showcase Tailwind's @apply feature with one of Tailwind's single-property utilities (which changes a single CSS declaration). When showcased this way, @apply doesn't sound promising at all. So obvio

Feeling Like I Have No Release: A Journey Towards Sane DeploymentsFeeling Like I Have No Release: A Journey Towards Sane DeploymentsApr 23, 2025 am 09:19 AM

Deploying like an idiot comes down to a mismatch between the tools you use to deploy and the reward in complexity reduced versus complexity added.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment