A common WordPress effect is to add a class to the header, a back to top button or any other element once the visitor has scrolled down a bit, and remove it again at the top of the page. CSS then does the rest: a smaller sticky header, a shadow, a button that fades in.
This snippet adds a class to an element on scroll after a set number of pixels. It is plain JavaScript, so it works on block themes and pages that do not load jQuery.
The snippet
(function () {
var selector = '.element'; // Elements that get the class.
var className = 'active'; // Class added after scrolling.
var offset = 100; // Pixels to scroll before the class is added.
var elements = document.querySelectorAll(selector);
if (!elements.length) {
return;
}
var ticking = false;
function update() {
var scrolled = window.scrollY > offset;
elements.forEach(function (el) {
el.classList.toggle(className, scrolled);
});
ticking = false;
}
window.addEventListener('scroll', function () {
if (!ticking) {
ticking = true;
window.requestAnimationFrame(update);
}
}, { passive: true });
update();
})();
Change the three values at the top: the CSS selector of the element, the class to add, and how many pixels to scroll first.
How it works
- The script finds the elements once, then listens to the
scrollevent. Whenwindow.scrollYis larger thanoffset, every element gets the class; above it, the class is removed. requestAnimationFrameruns the update at most once per frame, and the listener ispassive, so scrolling stays smooth.- It also runs once on load, so a page that is opened halfway down (after a reload or a link to an anchor) gets the class right away.
- The older version of this post used jQuery’s
$. WordPress loads jQuery in noConflict mode, so$is not defined there and the script stopped with an error. Block themes often do not load jQuery at all.
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 need it). Under Script location tick Footer, set Footer Mode to Javascript, paste the code and publish.
Scripts Organizer prints header and footer code with the Conditions trigger on the front end, not with Everywhere, and adds the <script> tag itself. The footer is the right place: the elements already exist when the script runs.
Example CSS
For a header that gets a background and a shadow once the page scrolls, with var selector = '.site-header';, add this to your theme’s stylesheet or a Scripts Organizer header block with Header Mode CSS:
.site-header {
transition: box-shadow 0.3s ease, background-color 0.3s ease;
}
.site-header.active {
background-color: #fff;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
}
Customise it
- Several elements: use a selector list, for example
'.site-header, .back-to-top'. - Add the class to
<body>instead: use'body'as the selector and style children withbody.active .site-header. - Toggle a class when an element itself scrolls into view: see Add and Remove a Class on Scroll in WordPress.
Gotchas
- Elements added to the page later, for example by a popup or an AJAX filter, are not found. Move the
querySelectorAllline intoupdate()if you need them. - Animating
heightorpaddingon a sticky header can make the page jump.transformandbox-shadoware cheaper to animate.
In the Scripts Organizer library Import it with one click from Scripts Organizer.