Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

226
Views
Change div opacity when scrolling

I would like to have div elements fade in and out when scrolling over them by changing the opacity. It sounds really simple but can't get it to work.

The problem I have is that the div are in the middle of my page and not on top, so scrollTop shouldn't work right?

var fade = $('.b_wrapper');
var range = 400;

$(window).on('scroll', function() {
  var st = $(this).scrollTop();
  fade.each(function() {
    var offset = $(this).offset().top;
    var height = $(this).outerHeight();
    offset = offset + height / 1;
    
    $(this).css({
      'opacity': 1 - (st + offset - range) / range
    });
  });
});
.content {
  height: 100px;
}

.b_wrapper {
  background: lightgreen;
  margin-top: 40px;
  padding: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<div class="content"></div>
<div class="b_wrapper">
  <p>this is a div</p>
</div>
<div class="b_wrapper">
  <p>this is a div</p>
</div>
<div class="b_wrapper">
  <p>this is a div</p>
</div>
<div class="b_wrapper">
  <p>this is a div</p>
</div>
<div class="b_wrapper">
  <p>this is a div</p>
</div>
<div class="b_wrapper">
  <p>this is a div</p>
</div>
<div class="b_wrapper">
  <p>this is a div</p>
</div>

(JsFiddle)

almost 4 years ago · Santiago Trujillo
2 answers
Answer question

0

You can use the Intersection Observer API. It watches for changes in the intersection between a target element and its ancestor element or the viewport.

First, create a new observer with options:

let options = {
  root: null,
  threshold: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
}
let observer = new IntersectionObserver(callback, options);
  • root specifies either the ancestor (containing) element, e.g. with document.querySelector(), or the viewport with null.

  • threshold can take an array of intersection thresholds to watch for, which we'll directly use as opacity for our elements. So each time an element's intersection ratio with the viewport reaches one of these values, the callback is triggered. (You can use a function here to build the array if you want a more fine-grained sequence and don't want to write everything by hand.)

Next, add each element to the observer:

for (const target of document.querySelectorAll('.b_wrapper')) {
    observer.observe(target);
}

The callback is very simple, as we can directly use the provided intersectionRatio as opacity:

let callback = (entries, observer) => {
  entries.forEach((entry) => {
    entry.target.style.opacity = entry.intersectionRatio
  });
};

So much to get you started. Read the documentation, it's excellent and has many examples.

let callback = (entries, observer) => {
  entries.forEach((entry) => {
    entry.target.style.opacity = entry.intersectionRatio
  });
};

let options = {
  root: null,
  threshold: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
}
let observer = new IntersectionObserver(callback, options);

for (const target of document.querySelectorAll('.b_wrapper')) {
    observer.observe(target);
}
.b_wrapper{
  margin: 20px;
  padding: 20px;
  background: lightgreen;
}
<div class="b_wrapper"><p>this is a div</p></div>
<div class="b_wrapper"><p>this is a div</p></div>
<div class="b_wrapper"><p>this is a div</p></div>
<div class="b_wrapper"><p>this is a div</p></div>
<div class="b_wrapper"><p>this is a div</p></div>
<div class="b_wrapper"><p>this is a div</p></div>
<div class="b_wrapper"><p>this is a div</p></div>
<div class="b_wrapper"><p>this is a div</p></div>

almost 4 years ago · Santiago Trujillo Report

0

Probably not the best but here is my try :

  • On scroll, I check the position of every element to see wich one is the most centered

  • On window resize, I update the center of screen value

let centerOfScreen = window.innerHeight / 2;
let pageScroll;
let closestCenteredDivPosition = 999999;
let currentIndex;

let wrappers = document.getElementsByClassName("wrapper");
let positions = [];
for (let e of wrappers) {
  positions.push(e.offsetTop + e.offsetHeight / 2);
}

highlightMostCenteredDiv = () => {
  pageScroll = document.documentElement.scrollTop || document.body.scrollTop;
  let currentValue;
  for (let i = 0; i < positions.length; i++) {
    currentValue = Math.abs(positions[i] - centerOfScreen - pageScroll);
    if (closestCenteredDivPosition > currentValue) {
      closestCenteredDivPosition = currentValue;
      currentIndex = i;
    }
  }
  if (!document.querySelector(".current")) {
    wrappers[currentIndex].classList.add("current");
  } else {
    if (wrappers[currentIndex] != document.querySelector(".current")) {
      document.querySelector(".current").classList.remove("current");
      wrappers[currentIndex].classList.add("current");
    }
  }
  closestCenteredDivPosition = 999999;
}

highlightMostCenteredDiv();

document.addEventListener("scroll", highlightMostCenteredDiv)

window.addEventListener("resize", () => {
  centerOfScreen = window.innerHeight / 2;
})
body {
  margin: 0;
}

.wrapper {
  background-color: orange;
  height: 100px;
  width: 100%;
  margin: 50px 0;
  opacity: 0.3;
  transition: opacity 1s ease;
}

.current {
  opacity: 1;
}
<div class="wrapper"></div>
<div class="wrapper"></div>
<div class="wrapper"></div>
<div class="wrapper"></div>
<div class="wrapper"></div>
<div class="wrapper"></div>
<div class="wrapper"></div>
<div class="wrapper"></div>

almost 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!