Back to the blog

Responsive Layout Using CSS Grid

author image

Vijay Vittal

Technology | April 16, 2021

hero image

What’s so cool about this era in web development is that we’re capable of doing more and more with fewer lines of code, CSS Grid take the pain out of writing code for specific resolutions and viewports for most of the cases in building layouts and also contributed to writing more resilient code.

In this blog, we’ll start dipping our toes into the power of CSS Grid by building a responsive grid card layout for albums

We’ll kick off with an example by creating a common website layout for a grid of cards for the album layout below without using media queries.

grid21fee4e94571e3d9.gif

The albums list

<div class="albums">
  <div class="album">
      <div class="img-wrapper"><img src="https://via.placeholder.com/100" alt="img placeholder"></div>
      <div class="album-info">
          <div class="title">Album Title</div>
          <div class="album-name">Artist Name</div>
          <div class="description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum sed sint doloremque repellat, iste debitis.</div>
      </div>
  </div>
  <div class="album">
      <div class="img-wrapper"><img src="https://via.placeholder.com/100" alt="img placeholder"></div>
      <div class="album-info">
          <div class="title">Album Title</div>
          <div class="album-name">Artist Name</div>
          <div class="description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum sed sint doloremque repellat, iste debitis.</div>
      </div>
  </div>
  <div class="album">
      <div class="img-wrapper"><img src="https://via.placeholder.com/100" alt="img placeholder"></div>
      <div class="album-info">
          <div class="title">Album Title</div>
          <div class="album-name">Artist Name</div>
          <div class="description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum sed sint doloremque repellat, iste debitis.</div>
      </div>
  </div>
  ...
  ...
  ...
.albums {
    padding: 20px;
    /* Grid Styles*/
    display: grid;
    grid-gap: 20px;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

All elements will respond to window resizing and adapt accordingly. Though this might seem like a lot of code at first glance, the responsive behavior is done with only three lines of CSS Grid code, and without writing a single @media rule. Let’s break down the code to see what’s going on:

We have padding to separate the content from the edge of the screen, and then three lines of grid styles

1. The first line (display: grid;), indicates all album items inside the alumn container are now grid items.
2. The second line ( grid-gap: 20px;), A shorthand for row-gap and column-gap, creates a gap of 20px between each grid rows and columns
3. And that’s where the third line comes in. A lot of stuff is going on in that single property, so let’s go one step at a time.

The repeat() function

Generally speaking, what we usually do to define our columns and rows on a CSS Grid is to add the value for each track after defining the property, like this:

.element {
  /* This will result on four columns, each one of 1fr */
  grid-template-columns: 1fr 1fr 1fr 1fr;
  /* This will result on two rows, each one of 300px */
  grid-template-rows: 300px 300px;
}

Now, that’s quite dull. We can use the repeat() function to make that less verbose and easier to follow. The function takes two parameters:

1. The number of times to repeat the value.
2. The value itself.

After refactoring our code to use repeat(), we should expect the same results from these lines of code:

.element {
  /* this is the same as grid-template-columns: 1fr 1fr 1fr 1fr; */
  grid-template-columns: repeat(4, 1fr);
  /* this is the same as grid-template-rows: 300px 300px; */
  grid-template-rows: repeat(2, 300px);
}

Much cleaner, yeah?

The minmax() function

Now, the above examples are explicitly defining sizes for the tracks (1fr and 300px). That might work for some scenarios, but for our albumn example here, we need to be able to automatically calculate the size of the track, based on the width of the viewport, and automatically adjust the number of columns shown. To be able to do that, we’ll define a range of values using the minmax() function. What will we be defining? You’ve probably guessed by now: The minimum and maximum values we want these columns to be able to resize to.

In the album layout example above, we set our minmax() property to be 280px at its minimum size, and 1fr at its maximum size. fr units, if you’ve never heard of them, stand for fractional units.

That results in our tracks being 1fr when there’s plenty of space on our viewport (aka desktop resolutions), and 280px when there’s not enough space for both columns (like on mobile devices). That’s why they nicely grow when we make our browser wider since they’re taking the remaining space and equally dividing it across the existing columns. Now, moving to the last piece of the puzzle!

The auto-fit keyword

The auto-fit keyword allows us to wrap our columns into rows when there’s not enough space in our viewport to fit the 280px minimum value without overflowing the content. Now, with that last bit of code in place, we should be able to achieve this result:

grid21fee4e94571e3d9.gif

The album section

<div class="album">
    <div class="img-wrapper"><img src="https://via.placeholder.com/100" alt="img placeholder"></div>
    <div class="album-info">
        <div class="title">Album Title</div>
        <div class="album-name">Artist Name</div>
        <div class="description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum sed sint doloremque repellat, iste debitis.</div>
    </div>
</div>
.album {
    padding: 20px;
    display: grid;
    grid-template-columns: 100px 1fr;
    grid-column-gap: 15px;
    background: rgb(0 0 0 / 27%);
    box-shadow: 0 0 5px rgb(0 0 0 / 10%);
    border-radius: 3px;
}

Play with my code in codepen

Are media queries dead?

Back in the day, when we were building layouts using display: inline-block or floats, media queries made a lot of sense in order to change the size of our elements as the viewport got smaller. But now, with the incredibly powerful layouts that we’re able to create with a couple of CSS lines, you might feel tempted to think that media queries are doomed. I strongly disagree with that: I believe that we should change the way we think about them, and therefore use them differently.

we should use media queries to fix our layout when it breaks, rather than targeting devices, we’re not only able to detect screen sizes now, but pointer types as well. As a result, we can dig into a user’s system preferences and adapt our code for those who prefer reduced motion or whether we should use inverted colors. That means media queries are not dead; on the flip side, I’d say it’s an exciting time for using media queries, but we need to learn to use them right.

“Building robust layouts using modern techniques such as Flexbox or CSS Grid, will save you a bunch of time, code, and headaches."

That’s all, folks! A fully responsive website layout, using just three lines of CSS code. Not bad, huh? Make sure you check the source code and play around with this example on CodePen

Related Article:

Browse all categories