javascriptjquerycssreactjscss-animations

How do I delay a css animation till I have scrolled to the element in React?


I have built an animation similar to this and now I want to ensure that it will play only when the user has scrolled to a certain location such that the content being animated is actually visible. How do I do that inside a React App ?
I have tried reading up on the problem but most solutions either point to jQuery or Animate.css or waypoint js.


  1. Is there any way to do this without using any of these ?
  2. How does React and jQuery work together without causing a conflict ? (I ask because I am also using react-bootstrap and they explicitly state that they have built it from scratch to avoid using jQuery with React) Where should i even write the jQuery code ?

body{
  font-family: Helvetica, Arial, sans-serif;
}
.container{
  width: 50%;
  margin: 0 auto;
}
@keyframes load{
  from {
    width: 0%
  }
}
@-webkit-keyframes load{
  from {
    width: 0%
  }
}
@-moz-keyframes load{
  from {
    width: 0%
  }
}
@-o-keyframes load{
  from {
    width: 0%
  }
}

.bar{
  background-color: #EEE;
  padding: 2px;
  border-radius: 15px;
  margin-bottom: 5px;
  font-size: 14px;
  color: #FFF;
  font-weight: bold;
  text-shadow: 1px 1px 1px rgba(0,0,0,0.5);
}
.bar::before{
  content:  attr(data-skill);
  background-color: #f3b0ff;
  display: inline-block;
  padding: 5px 0 5px 10px;
  border-radius: inherit;
  animation: load 2s 0s;
  -webkit-animation: load 2s 0s;
  -moz-animation: load 2s 0s;
  -o-animation: load 2s 0s;
}

.bar.front::before{
  background-color: #ffcc33;
}
.bar.back::before{
  background-color: #a6cfe3;
}

.bar.learning::before{
  width: calc(20% - 10px);
}
.bar.basic::before{
  width: calc(40% - 10px);
}
.bar.intermediate::before{
  width: calc(60% - 10px);
}
.bar.advanced::before{
  width: calc(80% - 10px);
}
.bar.expert::before{
  width: calc(100% - 10px);
}
  <div class="container">
    <h1>Skill Set</h1>
    <div class="bar learning" data-skill="TDD"></div>
    <div class="bar back basic" data-skill="Python"></div>
    <div class="bar back intermediate" data-skill="C#"></div>
    <div class="bar front advanced" data-skill="CSS3"></div>
    <div class="bar front expert" data-skill="HTML5"></div>

  </div>


Solution

    1. You can always use a library like react-is-visible. This tracks the visibility of the component. You could then set a useEffect on the visibility variable, which could then add a class to your to-be-animated component once it becomes visible.

    Extended documentation from package to suit this answer

    import React, { useRef } from "react"
    import { useIsVisible } from "react-is-visible"
    
    const SomeComponent = () => {
      const nodeRef = useRef();
      const isVisible = useIsVisible(nodeRef);
    
      return (
        <div ref={nodeRef} className={`bar${isVisible ? ' animate' : ''}`}>
          {..content of div}
        </div>
      );
    }
    

    You will then need to edit your CSS as well

    .bar{
      background-color: #EEE;
      padding: 2px;
      border-radius: 15px;
      margin-bottom: 5px;
      font-size: 14px;
      color: #FFF;
      font-weight: bold;
      text-shadow: 1px 1px 1px rgba(0,0,0,0.5);
    }
    .bar::before{
      content:  attr(data-skill);
      background-color: #f3b0ff;
      display: inline-block;
      padding: 5px 0 5px 10px;
      border-radius: inherit;
    }
    .bar.animate::before{
      animation: load 2s 0s;
      -webkit-animation: load 2s 0s;
      -moz-animation: load 2s 0s;
      -o-animation: load 2s 0s;
    }
    
    .bar.front::before{
      background-color: #ffcc33;
    
    1. Why would you want jQuery and React to work together? React should be able to achieve what you want to achieve with jQuery!