CSS Scroll Snap is a feature implemented by most modern web browsers, but sometimes it just doesn’t behave as we would like to, and it can generate a lot of problems.
Just to name a few, it can prevent our scroll-based animations from getting triggered; it makes it impossible to use scrollable content inside the sections, it’s not fully compatible with non-fullscreen sections, lacks the functionality to add infinite loops, it doesn’t support mouse dragging and it can cause sections to be skipped in some web browsers.
Apart from that, I personally think that CSS Scroll Snap works way better when using a trackpad but not as well as I would expect when using a mouse. In those cases, it scrolls normally but then bounces to fit the section, resulting in a less smooth scrolling experience.
It’s a great feature for some scenarios and a not-so-great feature for many others.
So, if you are looking for alternatives, I’d recommend you use fullPage.js instead.
fullPage.js
fullPage.js is the king of the snap scrolling components.
If you are looking for maximum compatibility and consistent output among devices, fullPage.js is what you need.
Yes, it is using JavaScript, so if you are a CSS-only puritarian, this won’t serve you well, but guess what: nothing else will. The CSS-only solutions are those supported by the browsers and the web standards, and those will only include “CSS snap”.
With fullPage.js, you’ll not only have the flexibility of building complex sites on top of it, but you’ll also gain speed up the developing process.
“Yeah yeah, but… why fullPage.js? Can you be more specific?”
Sure! Here are a few reasons:
Develop Way Faster
Using CSS Scroll Snaps can be relatively easy. Especially if you take an example as your codebase. (This always helps!) But building the extra features on top of it or adapting it to your structure or needs can definitely take plenty of your time.
fullPage.js instead is super easy to implement.
This HTML structure is all you need:
<div id="fullpage">
<div class="section"><h1>Section 1</h1></div>
<div class="section"><h1>Section 2</h1></div>
<div class="section"><h1>Section 3</h1></div>
</div>
Code language: HTML, XML (xml)
Then you include the CSS and the JS scripts and vualá! The magic happens!
But things don’t end up here.
Do you need some navigation bullets for your page? Just use the option. navigation: true
.
Do you prefer the scrollbar to be visible? Just use scrollBar:true
Do you need to link a menu with each section so each item gets the active state when reaching its section? No problem! Just use menu: "#my-menu"
.
What about inner scrolling inside sections? That’s a default! Nothing to do from your side!
Do you want to use URL anchors or permalinks for your sections so you can have linkable sections? You have it! Just use the anchors
option or the data-anchor
attributes.
The list goes on and on:
- Keyboard navigation
- Lazy load
- Responsive options
- Autoplay/pause media elements
- Configurable scrolling speed
- Configurable delay to stick to a section
- Custom arrows for horizontal slides
- Support non-fullscreen sections (Ideal for footers!)
- Callbacks and methods
- …
I’d recommend you take a look at the fullPage.js examples page so you can have an idea of some of the things you can do out of the box.
CSS Scroll Snaps can look simple to use at first, but once you get into the developing phase, you might realize there are plenty of features and nice-to-have features that you are missing. Things that fullPage.js provides out of the box and are a no-brainer to use.
Have More Control
fullPage.js is a framework on which to rely to create a fully customizable full-screen navigation experience, and the snap feature is just one of them.
With fullPage.js you’ll be able to configure almost everything, while CSS Scroll Snaps will have plenty of limitations. Limitations you won’t be able to overcome.
And I’m not even talking about complex use cases. Small and simple things like configuring the scrolling speed, the easing effect or the delay to stick to a section won’t be possible with CSS Scroll Snaps.
fullPage.js also provides a set of methods, callbacks, and CSS state classes that will allow you to control the whole flow of the page. You will not have to implement your own JavaScript code to figure out which section is active, for example, or to play/pause videos when reaching or leaving a section.
Here’s an example of how easy it is to trigger any action once a section is fully visible in the viewport:
new fullpage('#fullpage', {
afterLoad: function(origin, destination, direction, trigger){
if(origin.index == 2){
alert("Section 3 ended loading");
}
}
});
Code language: JavaScript (javascript)
And if you need more, fullPage.js methods allow you to control the whole flow.
For example, some websites need to prevent users from scrolling further until they fill out a form or click a button. With fullPage.js you can just use the method setAllowScrolling(false)
. Then turn it on again using your own logic.
Or you might want to disable the “sticky sections” in a specific scenario. Just use setFitToSection(false)
and get it done.
Need to move or force a snap to a specific section? Easy! Use movetosection()
.
There are endless use cases where fullpage.js makes it way easier to create the functionality that you need for your site.
Get the Same Experience for Trackpad and Mouse
While I think the CSS snapping effect behaves quite well when using trackpads (at least the one from Apple computers), it doesn’t behave as well when using a traditional mouse wheel.
If you want the section to snap to the next with a single swipe/scroll, CSS Snaps might not be exactly what you need. In that case, fullPage.js behaves more consistently and provides the exact same experience for both scrolling devices: trackpads and mouse.
Avoid Skipping Sections
The design of CSS Scroll Snap was likely guided by the principle of never interfering with the natural behavior of the mouse wheel. I assume they tried their best to avoid what’s known as “mouse hijacking“, by giving the user the freedom to scroll the page fast or slow.
This is not necessarily a bad thing. However, it can also result in an unwanted experience.
Sometimes, the user will end up skipping multiple sections without actually wanting it. I’ve been able to experience it myself, and it can be quite annoying, too.
fullPage.js behaves differently in this scenario. It works by hijacking the scroll, and this allows fullPage.js to scroll only one section at a time per swipe/scroll. (Unless you decide to turn off what fullPage.js calls autoScrolling
)
It’s a Component
Being a JS component, it’s super easy to use it anywhere and get all its features out of the box. (Not just the scrolling behavior)
fullPage.js comes with components for React, Vue, and Angular, so it’s very easy to just import it and start using it right away in your framework of choice.
And if you are into WordPress, there’s also a component for all major builders: Elementor, Gutenberg, and Divi.