No Time Dad

A blog about web development written by a busy dad

Another CSS Grid Responsive Blog Template

Lately I’ve been working on creating what I’ve been calling “skeleton” layouts. Which is a large layout that creates the structure of a page. To my surprise, Google has coined these kinds of layouts as macro layouts. Which honestly is a better name. I’ll try to use it moving forward.

I’m also really into creating responsive macro layouts without media queries. It’s a fun challenge. And it somehow feels a little rebellious. Like I’m getting away with something. I often feel like I’m supposed to slog through the complexity and quirkiness of breakpoints to achieve the optimal responsive layout. A css trial by fire!

Anyways, the example here is a super simple css grid responsive blog template that doesn’t use any media queries. It instead relies on css grid repeat with auto-fill to figure out how many columns and rows should be displayed based on the screen size.

CSS grid is very good at this. And I’m starting to feel like a lot of my responsive design work should start by trying to get it working without media queries first, then go back and apply them as needed for tough edge cases. We’ll see if that turns out to be a good idea or not. My hunch is that for simple designs it will be. It might also turn out to be a huge waste of time. Who knows.

blog-responsive

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="styles.css" />
    <title>Blog Template</title>
  </head>
  <body>
    <header>AwesomeBlog</header>
    <main>
      <h1>Posts</h1>
      <div class="posts">
        <div class="post">
          <div class="post__header">
            <a href="#post">Blog Post</a>
          </div>
          <div class="post__content">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
            eiusmod tempor incididunt ut labore et dolore magna aliqua.
          </div>
        </div>
        <!-- Omitted more blog post divs to save space -->
      </div>
    </main>
  </body>
</html>
/* styles.css */

/* Resets */
* {
  box-sizing: border-box;
}

html,
body {
  padding: 0;
  margin: 0;
}

/* Main styles */
a {
  text-decoration: none;
  color: black;
}

header {
  padding: 1rem;
  background-color: lightcoral;
  font-size: 2rem;
  font-weight: 600;
  text-align: center;
}

main {
  padding: 1rem;
}

.posts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
}

.post {
  padding: 1rem;
  border: 2px solid lightgray;
  border-radius: 0.5rem;
}

.post__header {
  margin-bottom: 0.5rem;
  font-size: 1.5rem;
  font-weight: 600;
}

The selector doing the bulk of the work here is .posts. It initializes the grid and defines the grid-template-columns using repeat with auto-fill. The auto-fill is what tells the browser to figure how many columns and rows there should be based on the screen size. The other clever piece of this grid-template-columns is the minmax function which sets the minimum card width to 15rem and the max to fill the available space via 1fr.

.posts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
}

This responsive blog template layout can also be achieved using flexbox (as shown below). The problem with this approach becomes apparent when you don’t have enough blog post cards to fill an entire row. In that case, the cards would stretch to fill the row. In my opinion, it looks nicer if the cards keep a uniform width and there is whitespace shown when there aren’t enough cards to fill a row.

.posts {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 1rem;
}

.posts .post {
  flex-basis: 15rem;
  flex-grow: 1;
}