CSS-only horizontally-scrolling cards with snapping

twitter logo github logo ・1 min read

It's a common design problem to have content cards to lay out in different arrangements in various viewports. In this exploration, I wanted to see how cards might be more effectively organized using a simple design pattern of a scrolling horizontal list. Try it on mobile:

It's implemented with CSS, and doesn't require any scripting for the layout or interactions. Lozad is used for lazy-loading.

There's some nice hover effects in place, CSS custom properties, and I use a simple CSS mask gradient on the edge to indicate there are more cards. To-do: Enable tabindex for accessibilty.

I experimented with more robust CSS grid layout for the cards, but I found after playing with it on mobile it was overkill.

twitter logo DISCUSS (11)
markdown guide

Awesome, I need to make use of scroll-snap-type.

Have you thought about users that might not have horizontal scrolling on their mouse? I'm not sure how common that is.


I don’t know a single person with a horizontal scrolling wheel/button on their mouse (except myself, of course). However, just about everyone I know uses a MacBook or other laptop with a trackpad that allows for horizontal scrolling :)


You can hold Shift + Scroll and it will go horizontally. Though it's not very intuitive or common knowledge. It's generally not a great idea to design desktop interfaces where horizontal scrolling is necessary for that reason, despite having trackpads and such.


Part of the rationale in my mind (which this conversation is helping clarify!) is to 1.) enhance the touch experience and optimize for the touchscreen context, and 2.) provide a decent layout for desktop. On wider viewports, my original plan was to simply be able to see all the cards (which of course, only works if you have a small number of cards).

What's interesting is this reveals how affordances for mouse users pull us into Carousel territory, with arrows/buttons for navigation, or other means of navigating. Then we're in JS territory (not bad of course) for interactions. I'll admit I've implemented carousels (in the trenches with you, Jeremy!) but not designed them from the ground up.

At the least, looking at say, Netflix's examples, it makes sense to have some arrows at the end of the rows to go back and forth. Progressive enhancement.


Another idea was to have it grabbable and let the mouse users just grab & drag. Cursor change could do that. Not sure most users would think to do so though. User test all the codepens! ;)


Yes, that works. I solved this in another way on a lower budget site. I went with multiple rows of cards and an expand link. This changes the entire row from a horizontal scroll to a simple list.


Or maybe just add some buttons to swap the cards and let this functionality be secondary. But I guess it would be best having in mind all the edge cases where this won't be usable.


Kam, thank you, that was a nice tip! I've added those properties to the demo, and it seems to work correctly on mobile. πŸ™


Great project and hey, I live in Portland too.


Nice one! This is some useful stuff, will be trying it in next project. Thanks

Classic DEV Post from Jul 30

When Stack Overflow Goes Offline...

Allan White profile image
I'm a designer & developer with 25 years of experience doing UX, design, video, animation, and web development.