Swipe Views with CSS Snap Points: Building a More Efficient Mobile Web Navigation
Update 01 — April — 2018: Fixed some typos — Broke down the problems of traditional carousel into clearer points — broke down the advantages of Snap Points into clearer points — Added future work I will be doing on this topic.
The mobile web has been making a lot of progress in the last year or two and I have happily replaced few native apps on my phone with their web alternatives and today I’m a full-time user of Twitter Lite and Instagram PWA.
For a long time the responsive mobile web has been hierarchical however, native apps has flattened the vertical hierarchies in their main views and implemented a very popular pattern sometimes called “horizontal paging” which provides the users with an efficient horizontal navigation from one tab to another using a simple left or right gestures and makes the relevant data or content in different app screens more accessible.
Not to my surprise, Twitter and Instagram PWAs — that I use daily as I mentioned earlier and they are 2 of my all-time favourite web apps — have brought in their native apps like navigation bars. Also not to my surprise, there is no swipe gesture and the absence of swipe gestures is not an app limitations but unfortunately a web platform limitation in my opinion.
Traditional Web “Carousel” Problems
The traditional, cross-browser carousel problems starts with the implementation requirements:
- A wrapper with overflow hidden.
- A wide wrapper of (number of screens*screen width) pixels.
- A minimum of 7 different events listeners: mousedown, mouseup, mouseleave, mousemove, touchstart, touchend, touchmove.
- On mouse or touch move we
translatethe wider container.
will-change:transformand whatever other magic we got and can add there to make that transition as smooth as possible.
Following those steps should give us a decent carousel with 50 bugs or so that is probably good enough for a hero banner but if we want to use it for an app views that have complex children layout, posts lists, comments, images, etc.. it will not do an amazing job for many reasons:
- If any children elements are meant to receive mouse or touch events, deciding if the parent should propagate or act first can be tricky and a further assistance form
touch-eventsmight be helpful to allow or block specific elements from receiving mouse or a touch events at some cases.
CSS Scroll Snap Points To The Rescue
CSS scroll snap points module helps us specify where a container’s scroll port should stop after the scrolling operation has been completed, read more about it on MDN and check Can I Use for browser compatibility. It is coming along nicely in all major browsers, the only no-support flags are in Chrome but the good news it’s being actively and almost daily worked on, check out the bug smashing progress here (Go Chrome!).
Few Problems CSS Scroll Snap Points Will Solve
- More efficient way to respond to children elements mouse & touch events since the parent does not require them anymore, there is no need to check on whether the parent wrapper has to respond or propagate.
- Ability to deal effortlessly with different size children or after children widths changes due to a container resize for example. CSS Snap Points will always snap to the begging of the child element or to any point we specify using
scroll-snap-coordinateproperty without needing to calculate the element’s widths.
Simple CSS Only Swipe Views Demo
If you using Edge, Safari or FireFox you can try my swipe views pen with CSS Snap Points:
Alternatively, you can check out this video I recorded of that pen:
CSS Snap Points Look Promising
scroll-snap-coordinate: 0 0;
Advanced Usage: CSS Grid with CSS Snap points
I have plans to experiment further more with them in the near future and learn more about their “cons” in real-world applications. I will also experiment with building a performant dynamic carousel and then will most likely publish a part 2 post as a follow-up.
Until then, if you have experimented with CSS Snap Points module, have a comment or anything to add to this post please comment below!
Thank you for reading 💚.