DEV Community

Cover image for Mastering Flexible Layouts: CSS Flexbox VS Grid for Responsive Design
Maya Shavin πŸŒ·β˜•οΈπŸ‘
Maya Shavin πŸŒ·β˜•οΈπŸ‘

Posted on • Originally published at mayashavin.com

Mastering Flexible Layouts: CSS Flexbox VS Grid for Responsive Design

In this post, we will discover different approaches to distribute a list of cards evenly, horizontally and responsively in different screen sizes using CSS Flex and Grid.

Table of Contents

The Challenge

In a gallery (or list) component, we often want to display items as cards, such as articles, products, or images. The number of cards per row can be flexible, depending on the container's width. Each card should expand to fill the available space and shrink to its minimum width as needed.

Design of list card in two different width sizes

The layout should remain consistent across screen sizes, with the cards distributed from left to right, wrapping to the next row as necessary. The cards should maintain equal height, width, and spacing between them.

Here’s a simple starting point for the HTML structure and CSS:

<ul class="list-items">
  <li class="item"> >
    <!--item's content-->
  </li>
  <!--more items-->
</ul>
<style>
  .list-items {
    list-style: none;
    max-width: 500px;
  }

  .item {
    border: 1px solid gray;
    padding: 10px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

With the above code, the browser displays the container according to the screen’s width but does not exceed 500px:

List of cards displayed in browser with minimum CSS

Currently, the items are not distributed horizontally. We’ll fix this next using CSS Flexbox.

Using CSS Flexbox to Create a Flexible List of Cards

CSS Flexbox provides a flexible and responsive layout structure using the display: flex property. To achieve horizontal flow, we use the flex-wrap property to wrap cards to the next row when necessary, and gap to define spacing between cards:

.list-items {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
Enter fullscreen mode Exit fullscreen mode

Now, the cards flow horizontally:

A list of horizontal distributed cards using CSS Flex

However, not all cards have the same width (e.g., Card 9 and Card 10). To fix this, we can set a fixed width for .item:

.item {
  /* other styles */
  width: 100px;
}
Enter fullscreen mode Exit fullscreen mode

This ensures all cards have the same width. But when the container's width changes, the cards cannot expand to fill the space. This leaves gaps at the end of each row, as shown below:

Cards distributed to the left and left some space each row on the right

We can try to address this using justify-content properties like space-between, space-around, space-evenly, or center:

Different results in different value of justify content

While these approaches work differently, none fully meet our goal of evenly distributing cards in size and spacing.

Instead, we can use flex-grow and flex-basis, which we’ll explore next.

Displaying Cards Evenly with flex-grow and flex-basis

The flex-basis property defines the initial size of a card before any extra space is distributed, while flex-grow: 1 (or simply flex: 1) allows the card to grow relative to its siblings. Combining these properties ensures that cards distribute evenly in size and spacing:

.item {
  /* other styles */
  flex: 1;
  flex-basis: 100px;
}
Enter fullscreen mode Exit fullscreen mode

Here’s the result:

Create App button in LinkedIn Developer dashboard

However, the last card still expands to fill the remaining space because it has no sibling to share it with. This breaks our consistency goal. To address this issue, let's turn to CSS Grid.

Using CSS Grid for a Flexible List of Cards

CSS Grid is a 2-dimensional layout system that organizes content into rows and columns. To create a flexible card layout, we can use the display: grid property:

.list-items {
  display: grid;
  gap: 10px;
}
Enter fullscreen mode Exit fullscreen mode

While CSS Grid supports many properties similar to Flexbox, such as gap and alignment options, it requires us to define the layout structure in advance. For a flexible layout, we can use grid-template-columns with auto-fit, minmax(), and repeat() functions:

.list-items {
  /* other styles */
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
Enter fullscreen mode Exit fullscreen mode

Here’s what the above code does:

  • repeat(<number>, <size>): Repeats columns of a specified size. Using auto-fit automatically adjusts the number of columns to fit the available space.

  • minmax(<min>, <max>): Defines the size range for each column, setting a minimum size of 100px and a maximum size of 1fr (1 fraction of the available space).

  • Combining these with grid-template-columns ensures the layout adjusts responsively.

And that's it! The result is a perfectly responsive layout:

Summary

CSS Flexbox and CSS Grid are powerful tools for creating flexible, responsive designs. While Flexbox excels at managing one-dimensional layouts, CSS Grid offers unparalleled flexibility for two-dimensional layouts. Understanding the strengths of each approach ensures you can choose the right tool for your design goals. I hope this article provides clarity and inspires you to create your next layout. If you have questions or feedback, feel free to reach out.

Happy coding! πŸš€

πŸ‘‰ Learn about Vue 3 and TypeScript with my new book Learning Vue!

πŸ‘‰ If you'd like to catch up with me sometimes, follow me on X | LinkedIn.

Like this post or find it helpful? Share it πŸ‘‡πŸΌ πŸ˜‰

Top comments (0)