Search code examples
javascriptcss-animationsonscrolllistener

Issues with triggering mulitple css animations on scroll


I'm not good with JS and struggle with triggering multiple CSS animations when they come into view.
So for I only manage to trigger one animation despite having three intersections that supposedly target the different elements. All I want to fill the bars to different widths which I have specified with keyframes. The section of the code is in the codepen. Could some help me out with it? https://codepen.io/asmmargod/pen/QWzOeQx

I tried adding new observers to target different elements but they come out with the same width.

I made separate observers for each element but the resulting efect shows the same animations on three elements

     const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
           entry.target.classList.add("active");
    }
  });
});
observer.observe(document.querySelector(".various__item--skills-fill-1"));

const observer1 = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add("active-2");
    }
  });
});
observer.observe(document.querySelector(".various__item--skills-fill-2"));
const observer2 = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add("active-3");
    }
  });
});
observer.observe(document.querySelector(".various__item--skills-fill-3"));`

Solution

    • ForEach your elements
    • Use CSS var() to customize the percentage

    const inViewport = (entries, observer) => {
      entries.forEach(entry => {
        entry.target.classList.toggle("active", entry.isIntersecting);
      });
    };
    
    const Obs = new IntersectionObserver(inViewport);
    document.querySelectorAll(".skill").forEach(el => Obs.observe(el));
    .skill {
      padding: 0.5rem 1rem;
      margin: 0.5rem;
      transition: all 4s;
      background:
        linear-gradient(90deg, #f00 0%, #f00 100%) no-repeat,
        linear-gradient(0deg, #0000 30%, #aaa 30%, #aaa 70%, #0000 70%) no-repeat
      ;
      background-size: 0%, 100%;
    }
    
    .skill.active {
      background-size: calc(var(--percent) * 1%), 100%;
    }
    <div class="skill" style="--percent:95;">HTML</div>
    <div class="skill" style="--percent:60;">CSS</div>
    <div class="skill" style="--percent:78;">JS</div>