Remember the days you needed JS to have a nice looking scrolling on your page (gallery, slide show etc.)? Say bye bye to JS and say hi to CSS Scroll Snap.

Long time ago, while CSS was on level 1, we’ve introduced with a property to scroll items and snap them to their container boundaries. But just Firefox had a support of this. But nowadays, we have FULL BROWSERS support. Let’s dive in and abandon the JS to make pure CSS scrolling job.

What is it good for?

Let’s say that we have to compare items on our website. We need an item to compare with a list of items. We don’t know the length of the list but we want to see them side by side with the main item. The list is long and have a scroll (let’s say on the X axis) and we want to see each item on the list by it’s full size and not part of it while scrolling.

Without this CSS property, if we’ll scroll the list, we need to be gentle with the scrolling and bring the item as close as we can to the boundaries of the container. But with this property, we just need to scroll it a just over the 50% and the browser will complete the scrolling till the position we wanted.

The best example will be if you’ll take your mobile device and scroll your homepage / list of apps to left, right, up or down a bit. The screen will slide to the next “page” (if you have) and you don’t need to fully scroll it. This is the same with this CSS property.

Scroll snap type

With CSS scroll type property, we are declaring that the container has a scrolling items and they need to be snap to the container boundaries. We can set the snap boundaries to none , x , y , block , inline or both

The difference between the options is:

none — no snap

x — snap to x axis

y — snap to y axis

block — snap to block axis (logical properties) — vertical axis (Same as Y axis)

inline — snap to inline axis (logical properties) — horizontal axis (Same as X axis)

both — snap to x and y (or inline and block) axis

There is another value that you need to declare on “scroll-snap-type” and you can choose between:

mandatory

proximity

To make it simple, mandatory will continue the scrolling as soon as the item will cross 51% of it’s width (on x / inline axis) or height (on y / block axis) while proximity need the item will scroll almost to it’s entire width or height.

The syntax (and values) for scroll-snap-type will be:

scroll-snap-type: none | [ x | y | inline | block ] [ mandatory | proximity ];

Now that we know where the items will be snap to, we can define how they will snap with scroll-snap-align on the scrolling items

An iOS fix

Thanks to Denys Mishunov that raised this fix for iOS users

To support iOS users, just add the following line

-webkit-overflow-scrolling: touch;

So the code will look like following:

.foo {

scroll-snap-type: x mandatory;

-webkit-overflow-scrolling: touch;

}

Scroll snap align

We can define the snapping to start , center or end

To do that, we need to define “scroll-snap-align” on the items themselves.

If we’ll define “scroll-snap-align: start” the items will be snap to the start of the container boundaries (according the axis we choose)

If we’ll declare “scroll-snap-align: center;” the items will be shown on the center of the container and we’ll see the edges of the surrounding items — as you can see on the image above.

In the following examples you can see 3 examples of scroll-snap-type X , Y and Both — All of them will snap to "start".

Scroll margin / Scroll padding

Both of these properties — scroll-padding and scroll-margin — are acting the same as padding / margin. They let us scroll with a space.

For example, using the property “scroll-padding: 10px;” will scroll the items one by one but with a space of 10px from the snap type (x, y, block, inline or both) boundaries

These properties don’t have full supported these days

Browser support

According to “caniuse” all of the browsers are supporting this property.

- IE / Edge needs the prefix -ms-

- Firefox is using an old writing of this property

On the last example you can see a “slideshow” with both of the scrolling (X and Y)

Last words