Pure CSS Slider — Using Scroll Snap

April 7, 2020
Pure CSS Slider — Using Scroll Snap

What is “Scroll Snap”?

Scroll Snap is pretty much what it sounds like — snapping or locking in to a certain position while scrolling. So, when scrolling through content like sections of a website or an image gallery, we often like to have whatever we’re scrolling through lock or snap in a particular position as a means of assisting with scrolling.

A great example would be iTunes’ Cover Flow view.



Pure CSS Scroll Snap uses properties which are a part of the CSS Scroll Snap Module. The system is based on a parent-child relationship between divs (as we’ll see in the following example) and uses the CSS properties — scroll-snap-type and scroll-snap-align respectively.

.parent {
  scroll-snap-type: x mandatory;

.child {
  scroll-snap-align: start;

Now, let’s go ahead and set up our workspace. For our example, we’ll be using a very basic, stripped-down, non-fancy version of the Cover Flow view. As we scroll horizontally through the X-axis, we can scroll through images and their captions to scroll and lock in onto the center of our screen. We’ll use images from UnSplash and use some dummy text for the captions.

Let’s look at the code.


 <div class="parent">
   <div class="child">
     <img src=""/>
     <div class="caption">
       <h3>Caption One</h3>
       <p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia.</p>

The div element with a class of .parent is our parent element. The .child div element is, you guessed it — the child. Inside this child element, we’ve set an image. Below this image is a .caption div element which contains a header and paragraph. For this example, we’ll duplicate the .child div 4 more times to make 5 slides.


body {
 font-family: sans-serif;
 font-size: 16px;
 font-weight: 300;
 background-color: #151515;
 margin: 0;
 height: 100vh;
 color: #fff;
p {
 max-width: 60%;
 line-height: 1.25rem;
 padding-left: 1rem;
 border-left: 2px solid rgba(255, 255, 255, 0.25);

For the body, you can see we’ve done nothing fancy. All we have here is a full viewport height of 100vh, reset the default browser margins, and set a background color because… why not?

For the paragraph, we’ve added a bit of left padding and a border to make it a little fancy. We’ve also set a max-width so that we don’t have too many words on a single line, therefore maintaining readability.

Let’s start with styling the .parent element.

.parent {
 display: flex;
 padding: 1rem;
 width: 80%;
 height: 100%;
 margin: 0 auto;
 background-color: #000;
 overflow-x: scroll;
 scroll-snap-type: x mandatory;

Most of the CSS you see here are basic styling except that we’ve used display: flex because we’re going to be using the CSS property flex-grow in the .child elements. The overflow property is used to hide spillovers the contain the .child elements within the set boundaries of the .parent. Also, without it, the snap functionality won’t work.

Now here’s the key player: the scroll-snap-type. This property accepts two arguments — the first is either x or y — which is either the x-axis or the y-axis. The second is the one we’ll stick to for this example, which is mandatory. This will make sure the child element locks back in place if you scrolled just a tiny bit. Larger scrolls amounts will snap you to the next slide. For more options, you can visit MDN Web Docs.

Now let’s see the CSS for .child element(s).

.child {
 position: relative;
 margin: 0.5rem;
 border-radius: 10px;
 scroll-snap-align: center;

Here, the position has a value of relative because the .caption div within will require a position of absolute. The margin is to create some space between each child element.

The key CSS for the .child element is the scroll-snap-align property. This property accepts up to two values for each the x and y axes, or block or inline, but we’re just going to be using one value, and here, we’ve used center (remember, we wanted to position the child elements at the center of the screen). Optionally, you could use start or end to position them.

Using the following CSS, we’re simply going to — 

  • style up the images so that they fit nicely inside the .child elements
  • style and position the .caption div while also giving it a fixed height for uniformity
  • style each of the .child elements using :nth-child() to give them different widths using flex-grow.
.child img {
 width: 100%;
 height: 100%;
 object-fit: cover
.child .caption {
 position: absolute;
 bottom: 0;
 padding: 1rem;
 height: 210px;
 background-color: rgba(0, 0, 0, 0.5)
.child:nth-child(1) {
 flex: 0 0 100%
.child:nth-child(2) {
 flex: 0 0 80%
.child:nth-child(3) {
 flex: 0 0 100%
.child:nth-child(4) {
 flex: 0 0 50%
.child:nth-child(5) {
 flex: 0 0 100%

And now this is what our browser output should look like (sans the image):

Browser output

Browser Support

Global browser support for Scroll Snap is at 92.07%. For more information, you can look up CanIUse.

And there you have it! It’s that simple and easy!

Maher Khan

Maher Khan

I love a challenge while trying to find the right balance between form and function and indulge in oddities — trying to make sense of them in the world of design. I work as the Creative and Frontend Lead of ARITS Limited and also serve as its Chairman.

Leave a Reply

Your email address will not be published. Required fields are marked *

Advancing Through Technology
Ground Floor • House 375 • Lane 6W
Baridhara DOHS • Dhaka • 1206 • Bangladesh
Email :
Call: ‭+880 19 0519 9835
Automation • Robotics • Information • Technology • Solutions
© 2019 ARITS Limited • Advancing Through Technology
All rights reserved.