A horizontally scrolling card row is one of the highest-value layouts on a marketing site: it shows six items in the space of three and works with a thumb-swipe on mobile. Here is the pure-CSS pattern we use in Peerless, and the two cascade traps that bite most implementations.
.cards--scroll {
display: flex;
flex-wrap: nowrap;
gap: 16px;
overflow-x: auto;
padding-bottom: 1rem; /* room for the scrollbar */
scrollbar-color: var(--primary-color) transparent;
scrollbar-width: thin;
}
.cards--scroll .card {
flex: 0 0 240px; /* fixed basis, no shrink */
}
Three things make it work: flex-wrap: nowrap keeps everything on one line, flex: 0 0 240px stops cards from shrinking to fit, and overflow-x: auto turns the overflow into a scroll instead of a blowout.
If your module also has a grid layout mode, .cards { display: grid } and .cards--scroll { display: flex } can tie on specificity — and then stylesheet order silently decides which one applies. Give the scroll variant a double-class selector (.cards.cards--scroll) so it outranks the base rule everywhere, always.
Most card grids carry a breakpoint rule like flex-wrap: wrap or width: 100% for small screens. That rule will happily stack your scroll row into a vertical list on exactly the devices where swiping matters most. Scope it: .cards:not(.cards--scroll).
.cards--scroll::-webkit-scrollbar { height: 8px; }
.cards--scroll::-webkit-scrollbar-thumb {
background: var(--primary-color);
border-radius: 4px;
}
Pair the WebKit rules with scrollbar-color and scrollbar-width for Firefox, and the scrollbar becomes a design element instead of a gray afterthought.
Want this as a drop-in module your editors can toggle per page? That is a four-to-eight-hour build.