Fade-in and slide-up effects in WordPress usually work the same way: an element gets a class when it scrolls into view, and CSS animates the change. This snippet adds the class is-visible to every element with the class show-on-scroll while it is on screen, and removes it again when it leaves.
It uses IntersectionObserver, so the browser tells the script when an element enters or leaves the screen. No jQuery and no loop that runs on every frame.
The snippet
The JavaScript:
(function () {
var selector = '.show-on-scroll'; // Elements to watch.
var visibleClass = 'is-visible'; // Class added while an element is on screen.
var once = false; // true = keep the class after the first time.
var elements = document.querySelectorAll(selector);
if (!elements.length) {
return;
}
if (!('IntersectionObserver' in window)) {
elements.forEach(function (el) {
el.classList.add(visibleClass);
});
return;
}
document.documentElement.classList.add('dpc-scroll-ready');
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add(visibleClass);
if (once) {
observer.unobserve(entry.target);
}
} else if (!once) {
entry.target.classList.remove(visibleClass);
}
});
});
elements.forEach(function (el) {
observer.observe(el);
});
})();
Example CSS for a fade-and-slide effect:
.dpc-scroll-ready .show-on-scroll {
opacity: 0;
transform: translateY(1.5rem);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.dpc-scroll-ready .show-on-scroll.is-visible {
opacity: 1;
transform: none;
}
@media (prefers-reduced-motion: reduce) {
.dpc-scroll-ready .show-on-scroll {
transform: none;
transition: none;
}
}
Then add the class show-on-scroll to any block (Advanced → Additional CSS class(es)) or builder element.
Add it with Scripts Organizer
In Scripts Organizer go to Code Blocks → Add New and give the block a name. Set Trigger location to Conditions and set Template to All (or only the pages that use the effect). Under Script location tick Header and Footer. Put the CSS in the header with Header Mode CSS, and the JavaScript in the footer with Footer Mode Javascript, then publish.
Scripts Organizer prints header and footer code with the Conditions trigger on the front end, not with Everywhere, and adds the <style> and <script> tags itself.
How it works
- The script finds all
.show-on-scrollelements once and observes them. The callback runs only when an element crosses the edge of the screen, which is much cheaper than the oldrequestAnimationFrameloop that measured every element 60 times a second. isIntersectingis true as soon as any part of the element is visible, the same rule as the old version.- The script adds
dpc-scroll-readyto<html>before it starts. The CSS only hides elements under that class, so if JavaScript fails or is off, the content stays visible. - Browsers without
IntersectionObservergetis-visibleon everything right away. - The CSS respects
prefers-reduced-motion: no slide, only the fade. - The earlier version wrapped the code in
jQuery, which block themes do not load on the front end, so it failed with “jQuery is not defined”.
Customise it
- Animate only once: set
var once = true;. The class stays after the first time. - Start a bit later: pass options to the observer, for example
new IntersectionObserver(callback, { rootMargin: '0px 0px -15% 0px' }). - Other class names: change
selectorandvisibleClassat the top, and the CSS to match.
Gotchas
- Elements added later (infinite scroll, AJAX filters) are not observed; call
observer.observe(el)for them. - On very long pages the browser may paint before the footer script runs, so hidden elements can flash briefly. Keep the hidden state subtle.
- For a header that reacts to scrolling, see Show navigation on scroll up.
In the Scripts Organizer library Import it with one click from Scripts Organizer.