auto hide a div / flash message after few seconds using css3 react

11,929

Solution 1

You can use CSS3 animations to hide your element after the specified time. Since am not able to run and see your code output, am not able to give the exact code snippet. You can dynamically add classes on your request success (you can use the same way you currently use, or there is a npm package called classnames) that will add those animations to show and fade your element.

Lets take this example:

animation: FadeAnimation 1s ease-in .2s forwards;

this will execute the FadeAnimation for 1 second with the ease-in style after 0.2 seconds the class is attached.

@keyframes FadeAnimation {
  0% {
    opacity: 1;
    visibility: visible;
  }

  100% {
    opacity: 0;
    visibility: hidden;
  }
}

This will transition the element from visible state to hidden state. You can add in between stages to your animation, by including some animation properties at respective percentage based on which place you want it to occur. You can similarly do it for removal as well.

Have a look at CSS3 Animations

Solution 2

I wanted to show an overlay with React and hide it with css after a few seconds and I bumped into your question, so I thought I show you how I made it. The answer of @jefree-sujit was of great help to me.

The end result is that actually we are showing a hidden overlay, then showing it via an animation in css, and then hiding it again.

So, in my render method I show my component like that:

{isPostFulfilled && <SuccessDisplay />}

(this part can be different depending on how you make your API calls, I use react-redux-fetch so I'm getting pending/fulfilled/rejected properties for my calls).

My SuccessDisplay component uses styled-components and is practically the overlay:

// @flow
import React from 'react';
import styled from 'styled-components';
import { BootstrapIcon } from 'skin';

export const Styling = styled.div`
  .success {
    animation: hide-animation 0.6s ease-in 0s;
    visibility: hidden;
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    height: 100vh;
    width: 100vw;
    background-color: rgba(0, 0, 0, 0.3);
    z-index: 100000;

    .ok-icon {
      font-size: 50px;
      cursor: default;
      opacity: 0.9;
      position: absolute;
      top: 48%;
      left: 48%;
      color: green;
      margin: 0 auto;
    }

    @keyframes hide-animation {
      0% {
        opacity: 1;
        visibility: visible;
      }

      100% {
        opacity: 0;
        visibility: hidden;
      }
    }
  }
`;

const SuccessDisplay = () => (
  <Styling>
    <div className="success">
      <BootstrapIcon icon="ok" className="ok-icon" />
    </div>
  </Styling>
);

export default SuccessDisplay;

The BootstrapIcon is rendering react-bootstrap's glyphicons.

The deal with the animation in this css snippet is that: it will run the hide-animation for 0.6 seconds, using the ease-in style (within those 0.6 seconds) and all this kicks in 0 seconds after the styles are loaded (instantly).

The important part is to set the visibility: hidden in our initial styles as well, since this is where we start from and where we're going to. After the animation ends (after 0.6 seconds) then we're falling back to our initial styles.

Hope this helps somebody in the future!

Share:
11,929
Deepak Kumar Padhy
Author by

Deepak Kumar Padhy

I am a Web Developer in ColdFusion/ Ruby on Rails. My Blog: http://cfdeepak.wordpress.com/

Updated on August 21, 2022

Comments

  • Deepak Kumar Padhy
    Deepak Kumar Padhy over 1 year

    I comparatively new to React environment .I have wrote a very basic component for bookmarking feature.

    Basically clicking upon favourite icon,

    it sends an ajax call > create a record in the db > on ajax success show a flash message "Page added to favourites."

    Its a toggle button, so upon clicking on it again ,

    it sends an ajax call > delete the record in the db > on ajax success i show a flash message "Page removed from favourites."

    Here is the component i wrote which works perfectly. But what i do not like is, using the setTimeOut function to hide the flash message. I fell like there must be other way (may be css) to achieve the same in React way.

    import React, {
      PropTypes
    } from 'react';
    import {
      Component
    } from 'aplus-base';
    import axios from 'axios';
    
    const API = "http://localhost:3000/favourites/toggle"
    const API2 = "http://localhost:3000/favourites/current_bookmark_status"
    
    @Component
    export default class Bookmark extends React.Component {
      static styles = require('./bookmark.sass')
    
      state = {
        bookmarked: '',
        message: "",
        alert: false
      }
    
      componentDidMount() {
        this.fetchData();
      }
    
      toggle() {
        const querystring = require('querystring')
        axios.post(API, querystring.stringify({
            current_page_key: '/marketing'
          }), {
            headers: {
              "Content-Type": "application/x-www-form-urlencoded"
            }
          })
          .then(response => {
            this.setState({
              bookmarked: response.data.bookmarked,
              alert: true
            });
            const message = response.data.bookmarked ? "Added to Favourites" : "Removed from Favourites"
            this.setState({
              message
            })
            setTimeout(() => {
              this.setState({
                alert: false
              });
            }, 2000);
          })
    
      }
      fetchData = () => {
        const querystring = require('querystring')
        axios.post(API2, querystring.stringify({
            current_page_key: '/marketing'
          }), {
            headers: {
              "Content-Type": "application/x-www-form-urlencoded"
            }
          })
          .then(response => {
            this.setState({
              bookmarked: response.data.bookmarked
            });
          })
      }
    
      render() {
        return ( <
          div >
          <
          i className = {
            this.state.bookmarked ? "icon icon-bookmarked" : "icon icon-bookmark"
          }
          onClick = {
            this.toggle.bind(this)
          }
          /> <
          div styleName = {
            `result ${this.state.alert ? "alert-shown": "alert-hidden"}`
          } > {
            this.state.message
          } <
          /div>     <
          /div>
        )
      }
    }
    .icon display: inline-block width: 30px height: 30px background: no-repeat center background-size: contain vertical-align: middle &.icon-bookmark background-image: url(../assets/bookmark.png) transition: all 1s linear &.icon-bookmarked background-image: url(../assets/bookmarked.png) transition: all 1s linear .result position: fixed top: 0 left: 40% width: 20% box-sizing: border-box padding: 4px text-align: center font-weight: bold .alert-shown opacity: 1;
    transition: all 250ms linear;
    .alert-hidden opacity: 0;
    transition: all 250ms linear;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>