At the end of the last post I wrote, which was about using jQuery to create buttons that automate scrolling across a set of divs laid out in a grid, I suggested that to fix the issue with scrolling not ‘snapping’ I investigate using CSS Scroll Snapping. This is exactly what I did right after I pressed ‘publish’ on that post and after a few hours of experimentation, I am pleased to say that it worked! Watch the quick video below to see a demonstration of the CSS Scroll Snap prototype fully functioning on a Surface Pro 4 and working nicely with touch interaction (scrolling with a mouse also works well).

Try the live version here!

How this differs from the jQuery prototype

Asides from having no directional buttons, the actual CSS and HTML markup is entirely different and there is no JavaScript required at all. We are seeing this more and more these days – CSS is becoming more and more powerful and is replacing what JavaScript can do more and more. The reason why the markup and CSS is so different to what I had written before is that CSS Scroll Snap only works on sites that use Flexbox, which introduces new syntax. I don’t often write in Flexbox, so it was interesting seeing how Flexbox works and experimenting with this modern method of writing CSS a little more.

The code

Let’s have a look at the code and see how this actually works.

HTML markup

It’s very similar to how I imagined it to look. At the end of the last post, I said that I imagined the HTML markup looking a bit like this:










And it ended up looking like this:



























Very, very similar indeed. The only key difference is that the divs that hold the content do not have a class associated with them. Traditionally, classes would be used to allow multiple elements (or divs) to share the same styles, thus reducing the amount of CSS code that needs to be written. In the code that I used, the divs containing the content inherit their style properties from the div class ‘container’ which these individual divs are held in. Look at the CSS below:

.container div {
    scroll-snap-align: start;
    height: 100vh;
    display: flex;
    color: white;
    font-family: Arial, Helvetica, sans-serif;

The key bits to note in this code are:

  • ‘scroll-snap-align: start;’ This dictates where the div ‘snaps’ to – ‘start’ is defined as the top edge of the div (when scrolling vertically) or the left side (when scrolling to the left) or the right side (when scrolling to the right). This means that the div always ‘snaps’ to the edge. You can also set this to ‘center’, meaning that the div would align to the centre point – but this would mean that the edges of the other divs might still be visible.
  • The height is set to 100vh – meaning that covers the entire viewport area.
  • The display is set to flex, meaning that this uses Flexbox.
  • White text and Arial font is being applied to all ‘div’ elements that do not have a class associated with them.

All of these properties are inherited by all divs that do not have a class associated with them.

The CSS for the container is below. A div that holds all of the ‘scroll snappable elements’ (let’s call them that) is required, in this case I’ve called it ‘container’, which is a pretty commonly-used name for such an element.

.container {
    display: grid;
    grid-template-columns: 100% 100% 100% 100%; /*define the number of columns - keep adding values to increase column count*/
    scroll-snap-type: both mandatory;
    overflow: scroll;
    border-radius: 8px;
    height: 100vh;

The display type of this container can be set to ‘grid’ and then the number of columns can be defined by typing in the width of each column as percentages (or pixels) after ‘grid-template-columns’. In this example I have four ciolumns because I’ve typed ‘100%’ four times, but I can add more by typing that a few more times.

The scroll-snap-type for the container needs to be set to:

scroll-snap-type: y mandatory;


scroll-snap-type: x mandatory;


scroll-snap-type: both mandatory;

You can also use ‘proximity’ instead of ‘mandatory’, but an axis for scrolling needs to be selected. If you use ‘y’ then that means that snap scrolling will only apply to vertical scrolling (scrolling along the Y axis). If you use ‘x’ then snap scrolling will only apply to horizontal scrolling (along the X axis). ‘Both’, which is what I have used, applies it to both axis – ideal for grids, such as the one I am making.

‘Proximity’ and ‘mandatory’ dictate how ‘precise’ the snap scrolling is – ‘proximity’ isn’t as precise as ‘mandatory’, meaning that the user has to drag the window further before it will snap into place.

The overflow of the container must be set to scroll, if this isn’t set then the scroll snapping won’t work at all. This means that you get two sets of scrollbars (the ones that the browser creates and the ones on the container), but these can be hidden quite nicely using the following code:

body {
    overflow: -moz-scrollbars-none; /*hide scrollbars in Firefox*/
    -ms-overflow-style: none; /*hide scrollbars in IE/Edge*/

::-webkit-scrollbar { /*hide scrollbars in Chrome, Safari and Opera*/
    display: none;

This is all you need to know to create websites that use CSS scroll snap!

The advantages of using CSS Scroll Snap

  • It will be supported for a long time to come with new browsers and software because it is so new.
  • It negates the need for any JavaScript – as long as you don’t need buttons to do the scrolling for you.
  • The code is clean and easy to use and uses Flexbox – a modern CSS framework.

The big disadvantage of CSS Scroll Snap

The big disadvantage is that this so new that a lot of browsers don’t support it yet. Look at the chart below from CanIUse:

The only two major browsers that have full support for this are Chrome and Safari. Firefox and Edge have partial support but it seems that Mozilla is not going to implement full support in the upcoming Firefox 66 and 67 releases, so it might be a while before Firefox gets full support. A lot of the lesser-used browsers like Opera and Samsung Internet Browser have no support for this at all, which could pose some usability or certainly aesthetic issues.

The code is so new that even Visual Studio 2019 Preview, which I’m using to write this with, does not recognise Scroll Snap as being valid CSS. This is the very very latest version of Visual Studio at the time of writing.

Visual Studio 2019 Preview doesn’t recognise the Scroll Snap code.

Happily, this will likely be a mobile app, so let’s look at the market share of mobile browsers at the moment in the UK. I’m showing only the UK because this is the country where our app will be used.

Source: StatCounter Global Stats – Browser Market Share

Safari and Chrome are the most widely used

However, Scroll Snap only works on the very latest versions of these browsers. Chrome 69 is the first version of Chrome to support Scroll Snap and on the Safari side you need to have Safari 11 or 12 which comes with iOS 11 or 12, respectively.

The browser version share for the UK is shown below:

Source: StatCounter Global Stats – Browser Version Market Share

Chrome 72 is the most common version of Chrome, holding 14.4% of the share and Chrome 71 holds 12.41% of the share. These two browsers are compatible with Scroll Snap, but Chrome for Android is just shown as one entity that holds around 16% of the share. Similarly, Safari is shown as just one browser. To understand which version of Safari iOS users are capable of running, let’s look have a look at the iOS version share in the UK.

Source: StatCounter Global Stats – iOS Version Market Share

iOS 12.1 holds the biggest share with 73.1% of all iOS devices in the UK running the OS. iOS 11.4 came second with a 7.4% share and iOS 10 and older old less than 3.86% of the share. Safari 11 cannot be used on iOS 10 or older, so we would be alienating approximately 3.86% of Apple device users in the UK by implementing CSS Scroll Snap.

As for Android, Chrome 72 requires at least Android 5.0 to run. Here is the Android market share in the UK:

Source: StatCounter Global Stats – Android Version Market Share

The top five most common versions of Android in the UK are all compatible with the latest version of Chrome for Android, so compatibility might not be a big issue.

All things considered, device compatibility may not be a big issue. We would need to ensure that users were using the latest version of Safari or Chrome on their device. Perhaps a script could run on the page that informs the user to update their browser if it detects that an older version is installed. For the sake of a prototype to demonstrate to the Broads Authority on May 3rd however, we can use CSS Scroll Snap and run it in a modern browser.


StatCounter Global Stats. (2019). Browser Version Market Share United Kingdom | StatCounter Global Stats. [online] Available at: [Accessed 11 Mar. 2019]. (n.d.). Can I use… Support tables for HTML5, CSS3, etc. [online] Available at: [Accessed 11 Mar. 2019]. (2018). Control Page Scroll in CSS Using Scroll Snapping. [online] Available at: [Accessed 11 Mar. 2019].

Kohler, M. (2018). Practical CSS Scroll Snapping | CSS-Tricks. [online] CSS-Tricks. Available at: [Accessed 11 Mar. 2019].

StatCounter Global Stats. (2019). Mobile & Tablet Android Version Market Share United Kingdom | StatCounter Global Stats. [online] Available at: [Accessed 11 Mar. 2019].

StatCounter Global Stats. (2019). Mobile & Tablet iOS Version Market Share United Kingdom | StatCounter Global Stats. [online] Available at: [Accessed 11 Mar. 2019].

StatCounter Global Stats. (2019). Mobile Browser Market Share United Kingdom | StatCounter Global Stats. [online] Available at: [Accessed 11 Mar. 2019].