Build a Responsive Card Grid with CSS Flexbox
• Updated 5/26/2026 • CSSFlexboxResponsive DesignWeb DevelopmentBeginner
Challenge Goal
In this beginner-friendly CSS coding challenge, you will build a responsive product card grid using Flexbox. The layout should adapt to different screen sizes, showing multiple cards per row on larger screens and a single card per row on mobile devices.
What You Will Build
You will style a simple product showcase page with six cards. Your goal is to use CSS Flexbox to create a clean, centered, responsive card layout.
The final layout should display:
- Four cards per row on large desktop screens.
- Two cards per row on tablet-sized screens.
- One card per row on mobile screens.
Concept Overview
Flexbox is a CSS layout system that helps you arrange items in rows or columns. It is especially useful for navigation bars, card layouts, buttons, and sections where items need flexible spacing and alignment.
In this challenge, you will practice:
- Creating a flex container with
display: flex;. - Allowing items to wrap with
flex-wrap: wrap;. - Centering items with
justify-content: center;. - Adding consistent spacing with
gap. - Controlling card width with
flex-basis. - Using media queries for responsive breakpoints.
Example
Here is a simple Flexbox card container:
.card-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1.5rem;
}
.card {
flex: 0 1 250px;
}
This allows cards to line up in rows, wrap when there is not enough space, and stay centered inside the container.
Coding Challenge
Use the starter code below and update the CSS to make the card grid responsive. Focus on Flexbox only. Do not use CSS Grid for this challenge.
Requirements
- Create a product card layout using Flexbox.
- The card container must use
display: flex;. - The cards must wrap onto new rows when needed.
- Cards must have consistent spacing between them.
- The layout must stay centered horizontally.
- On screens wider than
1024px, display four cards per row. - On screens from
768pxto1023px, display two cards per row. - On screens narrower than
768px, display one card per row. - The page must remain readable and usable on mobile devices.
Input and Output
Input
This challenge does not require user input. You will write CSS styles for an existing HTML structure.
Output
When opened in a browser, the product cards should automatically rearrange based on the screen width.
Desktop: 4 cards per row
Tablet: 2 cards per row
Mobile: 1 card per row
Constraints
- Use Flexbox for the layout.
- Do not use CSS Grid.
- Do not use external CSS frameworks.
- Do not use JavaScript.
- Keep the HTML structure unchanged.
- Only update the CSS.
Hints
- Add
display: flex;to the card container. - Add
flex-wrap: wrap;so cards can move to the next row. - Use
gapto create spacing between cards. - Use
justify-content: center;to center the rows. - Use
calc()to control the card width while accounting for gaps. - Use media queries to change card widths for tablet and mobile screens.
Starter Code
Copy this starter code into your project. Complete the missing Flexbox styles in styles.css.
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Card Grid</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<h1>Product Showcase</h1>
<section class="card-container" aria-label="Product cards">
<article class="card">
<h2>Product 1</h2>
<p>A short product description goes here.</p>
</article>
<article class="card">
<h2>Product 2</h2>
<p>A short product description goes here.</p>
</article>
<article class="card">
<h2>Product 3</h2>
<p>A short product description goes here.</p>
</article>
<article class="card">
<h2>Product 4</h2>
<p>A short product description goes here.</p>
</article>
<article class="card">
<h2>Product 5</h2>
<p>A short product description goes here.</p>
</article>
<article class="card">
<h2>Product 6</h2>
<p>A short product description goes here.</p>
</article>
</section>
</main>
</body>
</html>
/* styles.css */
body {
margin: 0;
font-family: Arial, sans-serif;
background-color: #f9fafb;
color: #1f2937;
}
main {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
h1 {
text-align: center;
margin-bottom: 2rem;
}
.card-container {
/* Add Flexbox styles here */
}
.card {
background-color: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
Solution Walkthrough
Step 1: Create the flex container
Add display: flex; to .card-container. This makes the cards flex items.
Step 2: Allow wrapping
Add flex-wrap: wrap; so cards can move to the next row when the screen gets smaller.
Step 3: Add spacing and alignment
Use gap for consistent spacing and justify-content: center; to keep the cards centered.
Step 4: Set desktop card widths
Use flex: 0 1 calc(25% - 1.5rem); so four cards fit per row on large screens.
Step 5: Add responsive breakpoints
Use media queries to change the card width to two columns on tablets and one column on mobile screens.
Solution
/* styles.css */
body {
margin: 0;
font-family: Arial, sans-serif;
background-color: #f9fafb;
color: #1f2937;
}
main {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
h1 {
text-align: center;
margin-bottom: 2rem;
}
.card-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1.5rem;
}
.card {
flex: 0 1 calc(25% - 1.5rem);
box-sizing: border-box;
background-color: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.card h2 {
margin-top: 0;
}
.card p {
line-height: 1.6;
}
@media (max-width: 1023px) {
.card {
flex-basis: calc(50% - 1.5rem);
}
}
@media (max-width: 767px) {
main {
padding: 1rem;
}
.card {
flex-basis: 100%;
}
}
Why This Works
The .card-container becomes a Flexbox container, and each .card becomes a flex item. The flex-wrap property allows cards to move to new rows, while gap keeps spacing consistent. Media queries change the card width at specific screen sizes so the layout becomes responsive.
Stretch Goals
- Add a hover effect that slightly lifts each card.
- Add product images and make them responsive.
- Add buttons inside each card.
- Add a featured card style for one product.
- Use CSS variables for colors, spacing, and border radius.
- Rebuild the same layout using CSS Grid and compare the difference.
Quick Checklist
- Does the container use
display: flex;? - Does the container use
flex-wrap: wrap;? - Are the cards evenly spaced with
gap? - Does the desktop layout show four cards per row?
- Does the tablet layout show two cards per row?
- Does the mobile layout show one card per row?
- Did you avoid using CSS Grid?
Support
Keep CompileQuestHub free
If this challenge helped you, support more open tutorials and code examples.
Need More?
Request a topic or report an issue
Use the contact form to request follow-up tutorials or report broken code, missing files, or outdated links.
Page Info
Freshness and topics
Topic: CSS
Difficulty: Beginner
Reading time: 6 min read
Published: 5/22/2026
Updated: 5/26/2026
Before You Start
Prerequisites
- Basic HTML knowledge
- Understanding of CSS selectors
Outcome
What you will learn
- Apply Flexbox properties to create flexible layouts
- Use media queries to build responsive designs
- Control spacing and alignment with gap and justify-content
- Develop a mobile-first card grid without CSS Grid
Learning Path
CSS Foundations
Continue this sequence from the series page and move through the lessons in order.
Open seriesRelated
Keep going with nearby resources
Build an Accessible FAQ Accordion with HTML and CSS
Create a responsive, beginner-friendly FAQ accordion using semantic HTML, native details and summary elements, and CSS styling without JavaScript.
Create a Semantic Navigation Bar with HTML
Build a beginner-friendly semantic HTML navigation bar with a site name, accessible links, and simple CSS for a clean horizontal website header.
Build a Simple Contact Form Page with HTML
Practice HTML form elements by creating a clean, accessible contact form page that collects a user's name, email, and message.

