A step-by-step pattern for a swipeable, horizontally scrolling card row in a HubSpot module using pure CSS - flexbox, overflow-x, styled scrollbars, and the cascade traps to avoid.
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.
The core pattern
.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.
Trap one: a base rule wins the cascade
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.
Trap two: your mobile media query un-wraps it
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).
Styling the scrollbar
.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.
About the Author
Founder, Developer, Marketer of Sports Page.
Comments
July 20, 2026
Four CSS Classes That Make Peerless Blog Posts Easier to Read
Four utility classes already built into Peerless let you float images, caption them, and stack link lists, all from the…
July 12, 2026
What Makes Peerless Different From Other HubSpot Themes
The specific architecture decisions -- no build step, zero-margin modules, ITCSS layering -- that separate Peerless…
July 12, 2026
The Story Behind FCP Solutions and Peerless
Why FCP Solutions builds Peerless as its own base theme, and how the same theme now powers more than one production…
July 12, 2026
How to Pass Core Web Vitals on HubSpot CMS
A practical checklist for hitting good Core Web Vitals scores on HubSpot CMS -- images, fonts, third-party scripts, and…
July 12, 2026
The Anatomy of a High-Converting CTA
What separates a call-to-action that converts from one that gets scrolled past -- copy, contrast, and placement, broken…
July 8, 2026
Powering a Sports Portfolio: BuildingSportsPage on Peerless
How we built sportspage.io as a child theme of Peerless: ten custom modules, everything else inherited, and one repo…
