7 days of unlimited WordPress themes, plugins & graphics - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Web Design
  2. Flexbox

2 Ways to Build a Scrolling Card UI (Flexbox and CSS Grid)

Scroll to top
Read Time: 8 mins

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:

And here's the second version of our finished component that uses CSS Grid for the grid layout:

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:

The card layout on screens up to 499pxThe card layout on screens up to 499pxThe card layout on screens up to 499px

 On small screens, it will look like this:

The card layout on screens between 500px and 699pxThe card layout on screens between 500px and 699pxThe card layout on screens between 500px and 699px

 On medium screens, it will have this appearance:

The card layout on screens between 700px and 1099pxThe card layout on screens between 700px and 1099pxThe card layout on screens between 700px and 1099px

Finally, on large screens, it will look as follows:

The card layout on screens larger than 1099pxThe card layout on screens larger than 1099pxThe card layout on screens larger than 1099px

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:

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 divs to ensure that the link button will always sit at the bottom of the card.

Here's the markup:

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:

The card layout on small screens explainedThe card layout on small screens explainedThe card layout on small screens explained
  • 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:

The card layout on medium screens explainedThe card layout on medium screens explainedThe card layout on medium screens explained
  • 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:

The card layout on large screens explainedThe card layout on large screens explainedThe card layout on large screens explained
  • 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:

And the related CodePen demo where you can examine all the styles:

CSS Grid Card UI

In this second approach we’ll create the same card layout, but with CSS Grid.

The CSS Grid layoutThe CSS Grid layoutThe CSS Grid layout

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:

And again, the related CodePen demo where you can examine all the styles:

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!

Flexbox Tutorials on Tuts+

Flexbox is a notoriously tricky part of CSS, but don’t worry, we have you covered!

Advertisement
Did you find this post useful?
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.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.