The idea of only needing CSS to customize your scroll instead of playing with JavaScript sounds great, doesn’t it?
Today, I’m going to show you how CSS Scroll Snap helps you do just that.
I bet you’ve used some libraries to control the scrolling behavior of your website. I have, and I had a terrible time with some of them.
Some of these libraries can drag your page’s performance and user experience way down.
Not to mention that it’s a real pain to deal with all the bugs they sometimes generate as you add more complexity with your new design updates.
That’s why I prefer to use this simple CSS feature that allows me to get a beautiful scroll through my page without having to rely on JavaScript libraries.
These properties also help me save a ton of time.
In simple terms, CSS Scroll Snap makes the scroll snap, locking the viewport at a specific point (that you indicate) with each scroll.
A linear scroll, on the other hand, moves according to the rate of the controller — whether that be a mouse, touch gesture, or arrow keys.
Now, let’s see how CSS Scroll Snap works.
If you want to go straight to a real-life example, head over to the third section where I’ve built the Instagram carousel with a few lines of CSS code.
Let’s get started.
CSS Scroll Snap works by applying two primary properties: scroll-snap-type
and scroll-snap-align
.
Here is what you need to know about each:
scroll-snap-type
, is applied to the parent container. It accepts two arguments: the snap direction and the snap behavior:.container { scroll-snap-type: [ x | y | block | inline | both ] [ mandatory | proximity ]; }
About the snap behavior arguments: choosing proximity
makes the snap only appear at the nearest point to where the user stopped scrolling.
On the other hand, mandatory
makes the snap happen at the specific position you choose when the user is scrolling.
scroll-snap-align
, is applied to the container’s children.This is where you specify the snap point for the x-axis and the y-axis:
.children { scroll-snap-align: [ none | start | end | center ]{1,2}; }
Before we continue, it’s important to note that none of this is going to work unless you specify the container’s overflow and give it a fixed height.
Additionally, you should never use mandatory if the content inside one of your child elements is longer than the parent container. If you do, the user won’t be able to see that content.
There are two more properties we need to familiarize ourselves with:
scroll-padding
(applied to the parent container) is pretty much like the CSS padding property and acts as the offset. You also have scroll-padding-top
, scroll-padding-bottom
, scroll-padding-left
and scroll-padding-right
.scroll-margin
(applied to the container’s children) is also like the CSS margin property and serves as the outset. You also have scroll-margin-top
, scroll-margin-bottom
, scroll-margin-left
and scroll-margin-right
.If you are interested in learning more about all scroll snap properties and future ones, the Mozilla documentation is always a good place to start.
To help you get a better grasp on this concept, I made a little Instagram-like carousel on codepen.
See the live demo here:
CSS Scroll Snap – Instagram-like Carousel
No Description
As you can see, it includes seven boxes with different sizes.
What amazes me is that we don’t have anything else to do other than add the CSS lines below to automatically make the scroll snap to each box.
<style> .container { width: 60vw; height: 70vh; margin: 15vh auto; overflow-x: scroll; scroll-snap-type: x mandatory; color: white; background-color: oldlace; display: flex; align-items: center; } .child { margin-left: 0.5rem; height: 90%; scroll-snap-align: start; padding: 1rem; display: flex; align-items: center; justify-content: center; text-align: center; } .child:nth-child(1n) { background-color: darkorchid; flex: 0 0 80%; } .child:nth-child(2n) { background-color: indigo; flex: 0 0 60%; } .child:nth-child(3n) { background-color: navy; flex: 0 0 40%; } .child:nth-child(4n) { background-color: palegreen; flex: 0 0 50%; } .child:nth-child(5n) { background-color: yellow; flex: 0 0 80%; } .child:nth-child(6n) { background-color: orange; flex: 0 0 60%; } .child:nth-child(7n) { background-color: tomato; flex: 0 0 80%; } </style>
Solving this issue with only JavaScript would have required a lot of extra work.
Okay, now let’s get to the million-dollar question: cross-browser support.
As you can see here, the CSS Scroll Snap functionality is well supported across modern browsers.
The only issue you’ll encounter is with Internet Explorer, which requires an older version of the specs that you can find here.
Also, I would advise you to add the property -webkit-overflow-scrolling: touch;
to your container to support iOS devices.
That’s pretty much it!
It’s so simple, but there were times where this could have saved me hours of code. Try to implement a scroll snap using JavaScript and recalculate the snap point with each child element with different widths, and you’ll see what I mean.
If you have any questions or remarks, please feel free to let me know in the comments or to ping me on Twitter @RifkiNada. I always reply.
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowNitro.js is a solution in the server-side JavaScript landscape that offers features like universal deployment, auto-imports, and file-based routing.
Ding! You got a notification, but does it cause a little bump of dopamine or a slow drag of cortisol? […]
A guide for using JWT authentication to prevent basic security issues while understanding the shortcomings of JWTs.
Auth.js makes adding authentication to web apps easier and more secure. Let’s discuss why you should use it in your projects.
4 Replies to "How to use CSS Scroll Snap"
Hmmm that demo didn’t work in Chrome Mobile…
Firefox supports modern version of spec since version 68 (current ESR), you have outdated info…
You’re right, thanks for pointing that out.
Thanks for this article. Unfortunately there seem to be a couple Chrome bugs that make this property rather unusable. For example the following where a tick of the mouse scroll wheel scrolls 2 panels instead of one (https://stackoverflow.com/questions/58863384/increase-sensitivity-of-scroll-snapping-in-google-chrome). Do we know of any workarounds?