Changing an element background color on page scroll/viewport

Does anyone know of a simple plugin or snippet that can target an element (ie. div background color) and as it comes into view changes the background colour then reverts back to the original color once it is out of view? (I guess it’s exactly like a hover effect but instead of hovering over the element, the user is ‘browsing’ over it.)

Hi there ikandee,

that appears to be a very unusual request. :confounded:

If an element is out of view, surely it’s also out of mind.

It can not have a meaningful background-color.

Of course, being a “bald headed old fart”, it is quite
likely that I have totally misunderstood your post. :worried:

coothead

Perhaps the OP means when the element scrolls into view on the page? Something like this perhaps.

Just guessing though:)

Sorry… maybe I wasn’t being clear.

So if I had 4 divs stacked up on top of one another (and they had a blue background), as the page moves down each ‘active’ div changes to a pink background once it reaches the middle of the viewport.

You could still see the other divs surrounding the ‘active’ div but they remain the blue background until it to reaches the middle of the viewport.

Hi Paul,
Thanks for sharing, but it wasn’t quite the effect I was after.

Hope this is a more clearer explanation.

So if I had 4 divs stacked up on top of one another (and they had a blue background), as the page moves down each ‘active’ div changes to a pink background once it reaches the middle of the viewport.

You could still see the other divs surrounding the ‘active’ div but they remain the blue background until it to reaches the middle of the viewport.

(The point of this is to highlight to the user where they are in a serious of ‘steps’.)

But if something is showing in the view-port, could they not be reading anywhere?

AFAIK most computers don’t come with eye-tracking enabled

Unless you want to “guide” their reading position, which IMHO doesn’t seem like a very good thing to try to do.

This is a quite mockup of what I am trying to explain. Maybe it is more clearer.

Wouldn’t that be a bit distracting - they are trying to read element 1 but you have 3 highlighted.

It would for me. I usually read the top half or so of the view-port and rather than read doown as I would if it were print scroll up so that what I’m reading is in the top half of the view-port.

Granted, this is likely a result of my cat training me. (she has a habit of lying in front of the monitor thereby blocking the lower half)
And in part because I wear bifocals and it’s easier to scroll than it is to nod my head up and down as I read

So is this not possible?

I’m sure it’s entirely possible

1 Like

Something like this perhaps.

1 Like

YES! That is exactly what I was after Paul. Thank you again for your help. :smiley:

I can see in the javascript I have the ability to set a topLimit & bottomLimit - is that measuring a certain distance or padding?

winHeight is the viewport height and therefore topLimit is 20% from the top and bottomLimit it is 80% from the top. That means the target is the 60% in the middle if my math is correct.

  var winHeight = $(window).height(),
        topLimit = winHeight * .2,
        bottomLimit = winHeight * .8;

Remember to include the jquery library (unless someone else want to re-write into vanilla js) :smile:

Not as distracting as I thought it would be.
(I added a line of Bacon Ipsum and tweaked some CSS to test)

With judicial use it could be very nice.

Ok, thanks for the clarification Paul. You are a great asset to the Sitepoint community!

1 Like
addClass = function(el,cl) {
var re = new RegExp('(^|\\s)'+cl+'(\\s|$)');
if (!el.className.match(re)) el.className += " "+cl;
};
 
removeClass = function(el,cl) {
var re = new RegExp('(^|\\s)'+cl+'(\\s|$)');
if (el.className.match(re))
el.className=el.className.replace(re,' ');
};

var scrollHi = function() {
 [].forEach.call(document.querySelectorAll('.scroll li'), function(el) {
            var thisTop = (el.style.top || el.style.pixelTop || el.offsetTop || 0) - (window.pageXOffset ? window.pageYOffset : document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
            if (thisTop >= topLimit && (thisTop + (el.offsetHeight || el.clipHeight || 0)) <= bottomLimit) {
                addClass(el,'highlight');
            } else{
		 removeClass(el,'highlight');
           } 
         });
}; 

var winHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
        topLimit = winHeight * 0.2,
        bottomLimit = winHeight * 0.8;

    window.addEventListener('scroll', scrollHi, false );
1 Like

Thanks Stephen :smile:

No problem. I looked at your jQuery code and realised that I had vanilla JavaScript equivalents to everything you used so it was just a matter of replacing your commands one by one with equivalent code that I had already written.

Very useful. I need to study that a bit now. It doesn’t look too much different from the original either so I can follow quite easily.:wink: