Dynamically change background color on scroll

41,362

Solution 1

You need to smoothly interpolate the colors by taking into account the page's scroll offset (window.scrollY, or window.pageYOffset on older browsers).

The Samsung site is transitioning a solid color instead of a gradient, which is a bit simpler.

Like this (see CodePen):

const [red, green, blue] = [69, 111, 225]
const section1 = document.querySelector('.section1')
window.addEventListener('scroll', () => {
  let y = 1 + (window.scrollY || window.pageYOffset) / 150
  y = y < 1 ? 1 : y // ensure y is always >= 1 (due to Safari's elastic scroll)
  const [r, g, b] = [red/y, green/y, blue/y].map(Math.round)
  section1.style.backgroundColor = `rgb(${r}, ${g}, ${b})`
})

You can apply the same logic to the gradient colors.

Solution 2

I think you need to use the "transition" property of CSS.

body {
  background: green;
  transition: 0.3s all;
}

Then you can add, remove elements along with change color:

$(function() {
$(window).scroll(function () {
   if ($(this).scrollTop() > 50) {
      $(‘body’).addClass(‘colorChange’)
      $(‘header’).addClass(‘displayNone’)
      $(‘nav’).removeClass(‘navBackgroundStart’)
      $(‘nav ul’).addClass(‘addBlackBackground’)
   } 
   if ($(this).scrollTop() < 50) {
      $(‘body’).removeClass(‘colorChange’)
      $(‘header’).removeClass(‘displayNone’)
      $(‘nav’).addClass(‘navBackgroundStart’)
      $(‘nav ul’).removeClass(‘addBlackBackground’)
   } 
});
});

Solution 3

I tried to use the solution of atomiks with a custom end color but it was too difficult. I found myself a better solution by using chroma.js

You need to generate a scale with your two colors (or more) :

var scale = chroma.scale(['#1abc9c', '#e74c3c']).domain([0, $(document).height()]);
$(window).on('scroll', function () {
    $('.section').css('background-color', scale(window.pageYOffset));
});

Here I create a scale with the color I want and then I add a custom domain so that my scale can use the offset position which can go from 0 (top of the page) 3600 (bottom of my page). Or, you can try to get the scroll position value between 0 and 1 with some math.

Then, when we scroll, we can use our scale with the current scroll position. It will generate a RGBA color between our two colors before reaching the last one at the bottom of the page #e74c3c

Solution 4

This jquery code changes the background color of the body.

$(document).ready(function(){       
        var scroll_pos = 0;
        $(document).scroll(function() {
            scroll_pos = $(this).scrollTop();
            if(scroll_pos > 300) {
                $("body").css('background-color', 'blue');
            } else {
                $("body").css('background-color', 'red');
            }
        });
    });

Don't forget to add the transition css to get that effect you see in your example.

body {
  -webkit-transition: all 0.5s ease;
  -moz-transition: all 0.5s ease;
  -o-transition: all 0.5s ease;
  transition: all 0.5s ease;
}

Make the backgrounds of your section classes transparent.

.section1, section2 {
  background-color: transparent;
}
Share:
41,362

Related videos on Youtube

Hide
Author by

Hide

Updated on July 09, 2022

Comments

  • Hide
    Hide 5 months

    Is there any way to change background color dynamically on scroll?

    For example, refer this site(https://www.samsung.com/sec/smartphones/galaxy-note9/)

    When you first access that site, background color is blue.

    While scroll down, it's color change to black smoothly.

    Also see this site(codepen.io/Funsella/pen/yLfAG/)

    Second site is same with first. But it's color changed at once.

    But first site's color is not change at once.

    It changed gradually related to scroll position.

    body {
      height: 100vh;
    }
    .section1 {
      background-color: white;
      height: 100%;
    }
    .section2 {
      background: linear-gradient(#f05fa6, #ed1654);
      height: 100%;
    }
    <html>
    <body>
      <section class="section1">
        SECTION1
      </section>
      <section class="section2">
        SECTION2
      </section>
    </body>
    </html>

    Above code is what I'm worked on.

    Current it's color is split by each section.

    When I scroll down, I want to change color background-color: white -> background: linear-gradient(#f05fa6, #ed1654)

    Is there any solution about this?

  • Aquarelle
    Aquarelle over 2 years
    This is the answer I came here looking for. Thanks for the chroma tip, BTW; I'm going to end up using it, I think.

Related