How to add fade-in Transition on Text Changes
Tags: react, javascript, vue, tutorial
Published: 2020-07-28 02:47:01

Text transitions are usually preferred when you need to notify a user of any text 
being changed on screen and it just not make the experience better, but, also 
important when text content on website changes based on the user actions on the screen.

> For example, if you're on an e-commerce website and read the price of
> an item, but, you changed the quantity of the item and suddenly your
> shipping charges are increased, making it important to highlight those
> changes to the user.

I believe this is one of the use-cases where text transitions are required, 
also, React and Vue frameworks support Hot Module Replacement, updating only the particular modules. See the example below to understand how simple text transition can 
have an impact on user experience. 

For example: 

![animated correct ](https://dev-to-uploads.s3.amazonaws.com/i/de055hf6b9x66mz9icp6.gif)

You can observe the difference when the UI has no transition, we might have missed the change in the heading at first look. 

Before we start with any framework, the following things are common among various frameworks for transitions in entering and leaving transition states:

### Transition Stages

There are three stages in each state of transitioning, initial stage, transitioning stage and transition done stage, 
giving us total 3+3 stages for entering and leaving altogether. The naming convention may vary with a different framework, 
see in below image for better understanding.

![three-stages-of-transition](https://dev-to-uploads.s3.amazonaws.com/i/054ohmmz8m1lxjodvv8d.png)

 
### Transition Triggers
To trigger the transition, there are multiple ways, a few of them are as followed:
1. Adding/Removing a node from the DOM tree
2. Showing and hiding a node from UI (using display: none)
3. Adding/Removing items into the list
4. Dynamically updating the current node with a new node

For **text replace** transition, we will be using Dynamic node updating criteria where a new node/text content 
takes place of the old node/text content. 
 
Let's see how it can be implemented and understand the complexity with different frameworks.

## Vue JS Implementation

Vue has in-built `<Transition>` wrapper component which allows adding entering and leaving transitions for a component 
or a parent node wrapping multiple nodes. Refer below image for different classes available. 

![animated correct ](https://dev-to-uploads.s3.amazonaws.com/i/5tjc3nvd2prj1b5cqngt.jpg)

We will use Dynamic Component loading, mentioned above as one of the Transition triggers, for text change transition 
using `key` attribute to inform Vue of any change in node/content. 

Once we implement this, we see transitioning working as below: 

![vue transition default mode](https://dev-to-uploads.s3.amazonaws.com/i/jl0ad4g8qrj1txaan5oh.gif)

You can see that this is **NOT** what we desire, the problem is that the new text content is coming before the previous 
text content is hidden and due to this, both contents are visible for a fraction of second during transitioning.
This is what we call as `in-out` mode, which is set by default.

**How to solve this flickering issue?**

To make this transition smooth, we have to make sure that the transition of old text content is completed 
before new content transition starts. For that, we specify mode as `out-in` to prevent flickering. 
You can read more about transitions and modes in-depth [here](https://vuejs.org/v2/guide/transitions.html).

{% codesandbox vue-text-transition-example-nlvog runonclick=1 %}

<br>

##  React Implementation

Unlike Vue, in React, we have to import a separate transition library, [react-transition-group](https://reactcommunity.org/react-transition-group/)
 which provides specific Component wrappers like CSSTransition, Transition, SwitchTransition and TransitionGroup. 

For text replace transition specifically, we need two components, `CSSTransition` and `SwitchTransition`. It also has 3 stages of 
the text transition in both entering and leaving transition states just like Vue. Refer to below diagram to understand the classes.

![react transitioning classes](https://dev-to-uploads.s3.amazonaws.com/i/c3vl10kg2leh4rwsd3wh.jpg)

### CSSTransition 
It handles the transition on the content, like the timeout, transition class name, etc., It has support for following props: 

1. **Timeout**: You can define the timeout of the entering and leaving transition separately or as a common numeric time in milliseconds. 
2. **addEndListener**: You can define the method here for ending the transition. 
3. **ClassNames**: The name has been set as plural (with s), just to not mix it with React default way of adding CSS classes 
 on any node using className. This lets you define the parent class which will be used to define the transition. 
4. **In**: This prop lets you state when the transition classes are to be applied on the node/text content. It's a sort 
 of switch to turn on and off transition effects dynamically on DOM.  Vue's `<Transiton>` component has 
 no direct prop or method to trigger such functionality. You can read more about its various options [here](http://reactcommunity.org/react-transition-group/css-transition).

### SwitchTransition 
Similar to Vue, we need to specifically select the `out-in` mode for letting the old content transition to be over before new 
content transition kicks-off. For that, we need to use this separate component. You can read more about its various options [here](http://reactcommunity.org/react-transition-group/switch-transition)

{% codesandbox react-text-replace-transition-cz08h runonclick=1 %}

<br>

## Vanilla JS Implementation

We are removing and adding the same `fade` class with changed text content and using `innerHTML` which repaints
 the content enabling the transition effect (called as forced reflow). 

> By default, we add a fade out related properties to `.text` class so
> that once the fade class is removed, it can work just like
> 'fade-leave-active' in Vue or 'fade-exit-active' in React.


There are two methods by which you can add transition: 
1. **Timeout Centric**: In this, you have to manually mention the timeout of the leaving 
state of the transition. This is not a recommended way, because same time needs to be 
entered in CSS styles. The timeout part is being handled with the `setTimeout` method and `requestAnimationFrame` 
callback to prevent any [jank-like](https://googlechrome.github.io/devtools-samples/jank/) (drop in frame rate) experience. 

2. **CSS Centric**: Here we leverage `transitionend` JS event listener which updates when the one state of transition is over serving the purpose of timeout being used above. 

{% codesandbox vanilla-js-text-transition-example-hc7kq runonclick=1 %}


<br/>
Hope you got some basic idea about how implementation is different as per framework and in vanilla JS. Do share your queries in comment section below.