to content
Skip
Web Design Flexbox
2 Ways to Build a Scrolling Card UI (Flexbox and
CSS Grid)
George Martsoukos Last updated Jul 14, 2022
8 min
In this tutorial we’ll use modern CSS features like flexbox, CSS Grid
Layout, CSS Scroll Snap, and CSS Scrollbars to build an attractive
horizontal scrolling card UI.
We’ll create this in two different ways so that you get a good understanding of various CSS
properties. You can use this UI pattern in different parts of your sites, for example:
To present team members
To show featured or latest posts/products
To list testimonials
As with any new CSS features, you might see inconsistencies depending on the browser
you use to check the demos. For example, Chrome will show our custom scrollbar,
whereas Firefox will still show the default scrollbar. Keep this in mind, and be sure to
check caniuse.com for the browser support of various front-end features.
Our Scrolling Card UI
Check the first version of our finished component that uses flexbox for the grid layout:
EDIT ON
HTML CSS Result
Scrolling Card UI With Flexbox
Service 1 Service 2 Service 3
Lorem ipsum dolor Lorem ipsum dolor Phasellus ultrices
sit amet sit amet lorem vel
consectetur consectetur bibendum ultricies.
adipisicing elit. adipisicing elit. Ab In hendrerit nulla a
repudiandae ante dapibus
magnam harum pulvinar eu eget
natus fuga et quam.
repellat in maiores.
made by
Learn More Learn More Learn More
Resources 1× 0.5× 0.25× Rerun
And here's the second version of our finished component that uses CSS Grid for the grid
layout:
EDIT ON
HTML CSS Result
Scrolling Card UI With CSS Grid
Service 6 Service 7 Service 8
Donec ut tincidunt Aliquam eget nisl Vivamus eget eros
nisl. Vivamus eget auctor, sollicitudin id elit feugiat
eros id elit feugiat ipsum at, dignissim mollis. Nam sed
mollis. Nam sed ligula. Donec sem quis libero
sem quis libero tincidunt in elit et finibus tempor.
finibus tempor. pellentesque.
Integer posuere
metus ac massa
mollis euismod.
made by
Learn More Learn More Learn More
Resources 1× 0.5× 0.25× Rerun
Try scrolling each one so that half a card is visible at the edge—see how the scrolling
behavior automatically snaps the cards into position!
1. Determine the Layout
Let’s kick things off by discussing the project requirements.
We need to create an adaptive scrollable card layout. The number of cards that will appear
in view will change depending on the viewport size.
Here’s a helpful table where we register how our layout (grid) should behave on different
screens:
Screen Viewport Size Grid Columns Grid Gap
X-Small < 500px 1 10px
Small ≥ 500px 2 20px
Medium ≥ 700px 3 30px
Large ≥ 1100px 4 40px
To visualize things, on extra small screens, the layout will look like this:
On small screens, it will look like this:
On medium screens, it will have this appearance:
Finally, on large screens, it will look as follows:
We also need to lock (snap) the visible cards in place, each time a user has finished
scrolling. This way we’ll always have an exact number of cards in view and we’ll avoid
seeing just a part of other cards; the scroll position will immediately shift to the starting
point of the closest card. This jump will produce an effect where each set of visible cards
will behave a bit like carousel slides.
This effect will be even more obvious on mobile screens where only a single card appears,
and as you swipe, the adjacent card slides in.
To better understand what I’m describing, consider the following video, or even better,
check the demos with various screen sizes:
A Scrolling Card UI With Scroll Snap Behavior
Kuopio vs HIFK
Suomen Cup
(Finland) 1.32 4.9 7.5
22/06/2023 - 14:00 BET NOW
Advertisement
2. Define the HTML Markup
We’ll use a pretty straightforward structure for this: a container element with a heading
and a list of cards inside it. Each card will contain a title, content, and link. We’ll wrap these
elements around some extra div s to ensure that the link button will always sit at the
bottom of the card.
Here's the markup:
1 <div class="container">
2 <h2>...</h2>
3 <ul class="cards">
4 <li class="card">
5 <div>
6 <h3 class="card-title">...</h3>
7 <div class="card-content">...</div>
8 </div>
9 <div class="card-link-wrapper">
10 <a href="" class="card-link">...</a>
11 </div>
12 </li>
13 <!-- more cards here -->
14 </ul>
15 </div>
3. Specify the Main Styles
To build the desired layout and especially the grid, we can use different layout techniques.
We’ll start with a flexbox approach and then continue with a CSS Grid one.
For simplicity, we’ll only discuss the important CSS parts.
All cards will live inside a container that will have a 1400px width.
Flexbox Card UI
The key things about the card wrapper:
It will be a flex container.
It will have overflow-x: scroll , as we want to scroll horizontally to look at all
cards.
We'll need a custom scrollbar that will match our brand colors, assuming our brand's
primary color is dark red.
The key things about each card:
It will be a flex container with flex-direction set to column . This means that the
flex items will be stacked vertically along the main axis.
As said earlier, the link button should always be at the bottom independently from the
title and content lengths of each card. So to achieve this uniformity, we'll give parent
link wrapper margin-top: auto .
We’ll give it flex-shrink: 0 as we don’t want to shrink and use the flex-basis
property to set its width. The flex-grow property doesn’t interest us, so we’ll keep
the default 0 value. The width will depend on the screen size and margin between
the adjacent cards. Let’s explain.
On extra small screens, all cards will have a width equal to the parent width.
To calculate the card width on small screens, we’ll do these calculations:
Total space between visible cards = 1 * 20px => 20px. We omit the space from the
last card.
The width of each card = calc(50% - 10px). The value 10px derived by calculating:
Total space between visible cards / Number of visible cards (20px / 2 => 10px).
To calculate the card width on medium screens, we’ll do these calculations:
Total space between visible cards = 2 * 30px => 60px. We omit the space from the
last card.
The width of each card = calc(calc(100% / 3) - 20px). The value 20px derived by
calculating: Total space between visible cards / Number of visible cards (60px / 3 =>
20px).
TIP
We need a three-column layout. So instead of writing calc(33.333% - 20px),
we’ll let browsers decide the exact percentage by adding a nested calculation.
To calculate the card width on large screens, we’ll do these calculations:
Total space between visible cards = 3 * 40px => 120px. We omit the space from the
last card.
The width of each card = calc(25% – 30px). The value 30px derived by calculating:
Total space between visible cards / Number of visible cards (120px / 4 => 30px).
To lock the viewport at certain elements after scrolling has finished, we’ll use the CSS
Scroll Snap feature. That said:
The card wrapper will receive the scroll-snap-type: x mandatory property value.
This ensures that the browser will snap to a snap point as soon as user scrolling
finishes.
Each card will receive the scroll-snap-align: start property value. This
determines the part of the card at which the scrolling should stop. Try to give it
another value like center to see the difference.
Try also scrolling without these two properties enabled to see the difference.
Here are the most important styles:
1 /*CUSTOM VARIABLES HERE*/
2
3 .cards {
4 display: flex;
5 overflow-x: scroll;
6 scroll-snap-type: x mandatory;
7 }
8
9 .card {
10 display: flex;
11 flex-direction: column;
12 flex: 0 0 100%;
13 scroll-snap-align: start;
14 }
15
16 .card .card-link-wrapper {
17 margin-top: auto;
18 }
19
20 .cards::-webkit-scrollbar {
21 height: 12px;
22 }
23
24 .cards::-webkit-scrollbar-thumb,
25 .cards::-webkit-scrollbar-track {
26 border-radius: 92px;
27 }
28
29 .cards::-webkit-scrollbar-thumb {
30 background: var(--darkred);
31 }
32
33 .cards::-webkit-scrollbar-track {
34 background: var(--thumb);
35 }
36
37 @media (min-width: 500px) {
38 .card {
39 flex-basis: calc(50% - 10px);
40 }
41
42 .card:not(:last-child) {
43 margin-right: 20px;
44 }
45 }
46
47 @media (min-width: 700px) {
48 .card {
49 flex-basis: calc(calc(100% / 3) - 20px);
50 }
51
52 .card:not(:last-child) {
53 margin-right: 30px;
54 }
55 }
56
57 @media (min-width: 1100px) {
58 .card {
59 flex-basis: calc(25% - 30px);
60 }
61
62 .card:not(:last-child) {
63 margin-right: 40px;
64 }
65 }
And the related CodePen demo where you can examine all the styles:
EDIT ON
HTML CSS Result
Scrolling Card UI With Flexbox
Service 1 Service 2 Service 3
Lorem ipsum dolor Lorem ipsum dolor Phasellus ultrices
sit amet sit amet lorem vel
consectetur consectetur bibendum ultricies.
adipisicing elit. adipisicing elit. Ab In hendrerit nulla a
repudiandae ante dapibus
magnam harum pulvinar eu eget
natus fuga et quam.
repellat in maiores.
made by
Learn More Learn More Learn More
Resources 1× 0.5× 0.25× Rerun
CSS Grid Card UI
In this second approach we’ll create the same card layout, but with CSS Grid.
Here are the modifications we’ll apply:
The card wrapper will be a grid container.
We’ll place all grid items as columns thanks to the grid-auto-flow: column
property value.
We’ll use the grid-auto-columns property to set the size for the columns. The
column size will depend on the screen size and the gap between each column. The
calculations are exactly the same as we did previously with the flex-basis
property. So, the values of the grid-auto-columns property will match the values of
the aforementioned flex-basis property at any screen size.
INFO
We applied the flex-basis property to the flex item, then the grid-auto-columns
property (and generally all the CSS Grid properties) to the grid container.
Here are the modified styles:
1 /*CUSTOM VARIABLES HERE*/
2
3 .cards {
4 display: grid;
5 grid-auto-columns: 100%;
6 grid-column-gap: 10px;
7 grid-auto-flow: column;
8 }
9
10 @media (min-width: 500px) {
11 .cards {
12 grid-auto-columns: calc(50% - 10px);
13 grid-column-gap: 20px;
14 }
15 }
16
17 @media (min-width: 700px) {
18 .cards {
19 grid-auto-columns: calc(calc(100% / 3) - 20px);
20 grid-column-gap: 30px;
21 }
22 }
23
24 @media (min-width: 1100px) {
25 .cards {
26 grid-auto-columns: calc(25% - 30px);
27 grid-column-gap: 40px;
28 }
29 }
And again, the related CodePen demo where you can examine all the styles:
EDIT ON
HTML CSS Result
Scrolling Card UI With CSS Grid
Service 8 Service 9 Service 10
Vivamus eget eros Duis id congue Pellentesque eget
id elit feugiat turpis. Donec eros eget justo
mollis. Nam sed sodales porta felis, efficitur
sem quis libero nec ultricies ante. fermentum.
finibus tempor. Nam placerat vitae
metus sit amet
tempor. Aliquam ac
dictum est.
made by
Learn More Learn More Learn More
Resources 1× 0.5× 0.25× Rerun
Conclusion
In this tutorial, we examined two ways of building a horizontal scrolling card UI. Along the
way, we went through various modern CSS features. This will have given you some new
knowledge and has hopefully inspired you to create UI layouts that take advantage of
some of the stuff we covered here.
If you can think of another way to build this layout, don’t forget to share it with us! As
always, thanks a lot for reading!
22/06/2023 - 14:00
Suomen Cup (Finland)
Kuopio VS HIFK
1.32 4.9 7.5
BET NOW
Advertisement
Flexbox Tutorials on Tuts+
Flexbox is a notoriously tricky part of CSS, but don’t worry, we have you covered!
Solving Problems With
CSS Grid and Flexbox: The
Card UI
Ian Yates
27 Jun 2022
How to Build a News
Website Layout with
Flexbox
Jeremy Thomas
01 Jun 2016
CSS Grid vs. Flexbox:
Which Should You Use and
When?
Anna Monus
18 Jul 2021
A Comprehensive Guide to
Flexbox Sizing
Anna Monus
06 Jun 2021
A Comprehensive Guide to
Flexbox Ordering &
Reordering
Anna Monus
05 Jun 2021
A Comprehensive Guide to
Flexbox Alignment
Anna Monus
23 May 2021
Kuopio vs HIFK
Suomen Cup
(Finland) 1.32 4.9 7.5
22/06/2023 - 14:00 BET NOW
Advertisement
Flexbox CSS Grid Layout HTML CSS UI Design
Did you find this post useful?
Yes No
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never
miss out on learning about the next big thing.
Sign up
George Martsoukos
George Martsoukos
George is a freelance web developer and an enthusiast writer for some of the largest
web development magazines in the world (Tuts+, SitePoint, LottieFiles, Scotch,
Awwwards). He loves anything related to the Web and he is addicted to learning new
technologies every day.
QUICK LINKS - Explore popular categories
ENVATO TUTS+
HELP
31,053 1,281 47,342
Tutorials Courses Translations
Envato Envato Elements Envato Market Placeit by Envato All products Careers Sitemap
© 2023 Envato Pty Ltd. Trademarks and brands are the property of their respective owners.