Transforming Color Themes On Scroll

Change the color theme of the content including background color and text color on scroll event using Javascript and CSS.




In this snippet, we will share with you the scroll animation effect that will change the background color, text color, heading/title font properties with animation using HTML, CSS, and Javascript!

Let’s start with the HTML structure.

HTML Structure

<body class="light" id="body">
  <section class="section" dd-theme="light">. . .</section>
  . . .
</body>

In the HTML structure, the theme class is applied to the body element, dynamically changed with class replacement triggered by scrolling. Now, let’s explore the detailed HTML content structure within the section.

Next, we will add HTML the content inside our section.

HTML Content Structure

<h1 class="title">Lorem ipsum Dolor sit!</h1>
<div class="clearfix"></div>
<div class="grid">
  <div class="grid3-5">
    <div class="section-image">
      <img src="images/pexels-zoe-pappas-1006965.jpg" alt="image" class="img" />
    </div>
    <p class="content">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Soluta iusto, ea
      laudantium quas repellendus quo tenetur sed sapiente perferendis, deserunt
      molestias qui, eos beatae voluptatibus obcaecati nemo autem vitae
      delectus.
    </p>
    <p class="content">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Soluta iusto, ea
      laudantium quas repellendus quo tenetur sed sapiente perferendis, deserunt
      molestias qui, eos beatae voluptatibus obcaecati nemo autem vitae
      delectus.
    </p>
    <div class="clearfix"></div>
    <br />
    <button class="form-btn">Explore!</button>
  </div>
</div>

The animation’s essence lies in the theme class, which can be chosen from options such as:

You can customize your own color themes according to your preferences. Here’s how you can create custom color themes using CSS variables.

CSS Varibales fo Themes

.light {
  --clr-primary: #000;
  --clr-secondary: #eae5e9;
  --clr-dots: #00000066;
  --size: 4rem;
  --weight: 900;
  --letter-spacing: 0;
}
.dark {
  --clr-primary: #ffc2f0;
  --clr-secondary: #000;
  --clr-dots: #ffc2f099;
  --size: 4rem;
  --weight: 800;
  --letter-spacing: 5px;
}
.solarized-light {
  --clr-secondary: #fdf6e3;
  --clr-primary: #586e75;
  --clr-dots: #586e7599;
  --size: 4rem;
  --weight: 800;
  --letter-spacing: 0;
}
.solarized-dark {
  --clr-secondary: #002b36;
  --clr-primary: #839496;
  --clr-dots: #83949699;
  --size: 4rem;
  --weight: 900;
  --letter-spacing: 3px;
}

Core CSS Sytles

CSS

body {
  font-family: var(--font);
  background-color: var(--clr-secondary);
  transition: var(--transition);
}
.container {
  width: max(800px, 70%);
}
.section {
  padding: 4rem 0;
  transition: var(--transition);
}
.section-image {
  position: relative;
  display: inline-block;
}
.section-image::after {
  position: absolute;
  content: "";
  background: radial-gradient(var(--clr-dots) 0%, transparent 20%);
  background-size: 15px 15px;
  padding: 10px;
  bottom: 0;
  right: -50px;
  width: 70px;
  height: 225px;
  z-index: -1;
  transition: var(--transition);
}
.section-image .img {
  border-radius: var(--radius);
  margin: 2rem 0;
}
.form-btn {
  display: inline-block;
  font-family: var(--font);
  font-weight: 700;
  border: none;
  background: var(--clr-primary);
  color: var(--clr-secondary);
  padding: 1rem 3rem;
  cursor: pointer;
  border-radius: var(--radius);
  transition: var(--transition);
}
.title {
  font-family: var(--font);
  font-weight: var(--weight);
  letter-spacing: var(--letter-spacing);
  font-size: var(--size);
  color: var(--clr-primary);
  transition: var(--transition);
}
.content {
  color: var(--clr-primary);
  transition: var(--transition);
}
.shapes svg {
  position: fixed;
  top: 100px;
  transition: var(--transition);
  fill: var(--clr-primary);
  width: 24px;
  height: 24px;
}
.shapes svg:first-child {
  right: 200px;
}
.shapes svg:nth-child(2) {
  right: 250px;
}
.shapes svg:last-child {
  right: 300px;
}

@media (max-width: 768px) {
  .light {
    --size: 2rem;
    --weight: 900;
    --letter-spacing: 0;
  }
  .shapes svg {
    top: 0;
  }
  .shapes svg:first-child {
    right: 0;
  }
  .shapes svg:nth-child(2) {
    right: 40px;
  }
  .shapes svg:last-child {
    right: 80px;
  }
}

Next, we will create a javascript function to change the theme/coloe on scroll.

Javascript

window.onscroll = onScroll;
let sections = document.querySelectorAll("[dd-theme]");
let total_section = sections.length;
let window_offset;
let window_half_height = Number(window.innerHeight) / 2;
let pointer = 0;
// Create the themes array with the values of class names.
let themes = [];
sections.forEach((c) => {
  themes.push(c.attributes["dd-theme"].value);
});
function onScroll(event) {
  let scroll_y = window.scrollY;
  // e.offsetTop / window_height
  window_offset = window.pageYOffset;
  let top_pos = Number(window.pageYOffset) + window_half_height;
  let section_top = sections[pointer].offsetTop;
  if (top_pos > section_top) {
    body.classList = themes[pointer];
    if (pointer != total_section - 1) {
      pointer++;
    }
  } else if (top_pos < section_top) {
    pointer--;
    body.classList = themes[pointer];
  }
}

In the above script, we have calculate the window top, scrollTop value, & section top value and according to that we have replaced the body class(theme) names.

Thank you for reading. I hope you guys liked the snippet.