Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?

Changing Background Color on Scroll with JavaScript



Live Demo / Download

Scroll animations appear to be a rising pattern currently, particularly for landing pages for SaaS and modern tech startups. These animations are conceived to beautify the person expertise, so long as they’re properly coded and never too intrusive for the ultimate person. We have beforehand created tutorials on this matter, just like the card waterfall animation on scroll or the gradient text reveal. At this time we’ll be including one other instance to the checklist: altering the background coloration of a web page as you scroll. This impact will will let you add dynamism to your design and make each part distinctive.



Structuring the HTML

On this demo, we are going to create a <principal> factor with 4 sections, every related to a special coloration from the Tailwind palette: Sky 200, Purple 200, Pink 200, and Emerald 200. To make sure clean coloration transitions, we cannot straight apply background colours to particular person sections. As a substitute, we’ll use the Intersection Observer API to find out which part is dominant and apply the corresponding background coloration to the principle container. This is the fundamental HTML construction:

<principal class="relative min-h-screen flex flex-col bg-sky-200 overflow-hidden">
    <div class="w-full max-w-5xl mx-auto px-4 md:px-6">
        <div class="pt-6 pb-12 md:pt-10 md:pb-20">

            <!-- Sky part -->
            <part>
                <!-- ... content material ... -->
            </part>

            <!-- Purple part -->
            <part>
                <!-- ... content material ... -->
            </part>

            <!-- Pink part -->
            <part>
                <!-- ... content material ... -->
            </part>

            <!-- Emerald part -->
            <part>
                <!-- ... content material ... -->
            </part>

        </div>
    </div>
</principal>
Enter fullscreen mode

Exit fullscreen mode

We have set the default background coloration of the <principal> factor to Sky 200 (bg-sky-200, which is the colour of the primary part) and ensured it fills no less than the peak of the viewport utilizing min-h-screen.



Making a JS class

Let’s create a file bg-scroll.js within the challenge’s root, and embrace it in our HTML doc:

<script src="./bg-scroll.js"></script>
Enter fullscreen mode

Exit fullscreen mode

In that file, we’ll outline a category named BgScroll exposing a init methodology for initializing the observer. This is the code to start out:

class BgScroll {
  constructor(factor) {
    this.factor = factor;
    this.init();
  }

  init() {
  }
}

// Init BgScroll
const el = doc.querySelector('[data-bg-scroll]');
new BgScroll(el);
Enter fullscreen mode

Exit fullscreen mode

On the finish of the file, we specify how you can initialize the category by including a data-bg-scroll attribute to the <principal> factor within the HTML:

<principal class="relative min-h-screen flex flex-col bg-sky-200 overflow-hidden" data-bg-scroll>
Enter fullscreen mode

Exit fullscreen mode



Creating the observer

Now, we’ll write the code to initialize the observer:

class BgScroll {
  constructor(factor) {
    this.factor = factor;
    this.sections = this.factor.querySelectorAll('part');
    this.observeSection = this.observeSection.bind(this);
    this.init();
  }

  observeSection(entries) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        console.log(entry.goal);
      }
    });
  }  

  init() {
    const observer = new IntersectionObserver(this.observeSection, { rootMargin: '-50% 0% -50% 0%' });
    this.sections.forEach(part => {
      observer.observe(part);
    });
  }
}

// Init BgScroll
const el = doc.querySelector('[data-bg-scroll]');
new BgScroll(el);
Enter fullscreen mode

Exit fullscreen mode

We have now created a brand new occasion within the constructor, known as sections, which comprises an array of all of the sections inside the principle factor. Within the init() methodology, we loop by way of this array and create a brand new observer for every part. The primary argument of the IntersectionObserver is the callback that will likely be executed each time a bit enters or exits the viewport (i.e., observeSection). The second argument is an choices object, which comprises the rootMargin property. Through the use of the values -50% 0% -50% 0%, we’re telling the IntersectionObserver to set off the callback when the part intersects an imaginary horizontal line positioned 50% from the highest of the viewport. For testing functions, we have added a console.log contained in the observeSection methodology to determine the dominant part as you scroll.



Altering the background coloration

Now that we all know which is the dominant part, we will apply the corresponding background coloration to the <principal> factor. To do that, we’ll outline the background coloration of every part utilizing a data-bg-color attribute and the Tailwind class of the corresponding background coloration:

<principal class="relative min-h-screen flex flex-col bg-sky-200 overflow-hidden" data-bg-scroll>
    <div class="w-full max-w-5xl mx-auto px-4 md:px-6">
        <div class="pt-6 pb-12 md:pt-10 md:pb-20">

            <!-- Sky part -->
            <part data-bg-class="bg-sky-200">
                <!-- ... content material .... -->
            </part>

            <!-- Purple part -->
            <part data-bg-class="bg-purple-200">
                <!-- ... content material .... -->
            </part>

            <!-- Pink part -->
            <part data-bg-class="bg-pink-200">
                <!-- ... content material .... -->
            </part>

            <!-- Emerald part -->
            <part data-bg-class="bg-emerald-200">
                <!-- ... content material .... -->
            </part>

        </div>
    </div>
</principal>
Enter fullscreen mode

Exit fullscreen mode

Contained in the observeSection methodology, we will now retrieve the attribute’s worth – which is entry.goal.dataset.bgClass – and apply it to the principle factor:

class BgScroll {
  constructor(factor) {
    this.factor = factor;
    this.sections = this.factor.querySelectorAll('part');
    this.observeSection = this.observeSection.bind(this);
    this.init();
  }

  observeSection(entries) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        // Take away all bg courses
        this.factor.classList.forEach(className => {
          if (className.startsWith('bg-')) {
            this.factor.classList.take away(className);
          }
        });
        // Add the right bg class
        this.factor.classList.add(entry.goal.dataset.bgClass);
      }
    });
  }  

  init() {
    const observer = new IntersectionObserver(this.observeSection, { rootMargin: '-50% 0% -50% 0%' });
    this.sections.forEach(part => {
      observer.observe(part);
    });
  }
}

// Init BgScroll
const el = doc.querySelector('[data-bg-scroll]');
new BgScroll(el);
Enter fullscreen mode

Exit fullscreen mode

And, as you could guess, we additionally take away all courses beginning with bg- to make sure just one background class is utilized.



Including a fade animation

To finish our impact, we’ll add a fade animation to the background coloration change. Merely add the transition-colors class to the <principal> factor. The ultimate and easiest step is so as to add a fade animation to the background coloration change. To do that, simply add the transition-colors class to the principle factor. Like this:

<principal class="relative min-h-screen flex flex-col bg-sky-200 transition-colors duration-700 overflow-hidden" data-bg-scroll>
Enter fullscreen mode

Exit fullscreen mode

We have now additionally added the duration-700 class to increase the animation length for a smoother impact.



Conclusions

Creating this dynamic background impact with the Intersection Observer is extremely straightforward. It takes simply round 30 strains of JavaScript, and no exterior libraries are required. Be at liberty to make your personal experiments and mess around with the code to match your particular wants. Do not forget to shoot us a message on Twitter if you happen to’ve already efficiently built-in the same impact into your website.



Add a Comment

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?