No Time Dad

A blog about web development written by a busy dad

Responsive Checkerboard with Flexbox

The basic idea with this element is that on large screens the element has two columns with multiple squares that alternate like a checkerboard, and on smaller screens it switches to a single column that stacks the squares. Honestly, I’m struggling to describe this one or give it a name. But, it’s a design style I’ve seen on a few different sites now, so I figured I’d give it a try.

Typically, the alternating squares would could text and an image. Again, it’s hard to describe. I did find a nice example on the SavvyCal website, however.

Large screen:

savvycal_large_checkerboard

Small screen:

savvycal_small_stacked

Before I jumped into inspecting the element in dev tools I took a minute to think about how this might be implemented. My first guess was that it was using css grid with media queries to change the number of columns. Maybe something like the below.

.grid {
  display: grid;
}

@media (min-width: 768px) {
  .grid {
    grid-template-columns: 1fr 1fr;
  }
}

While that does solve the problem of switching between a single column grid and a two column grid, it doesn’t do anything to address the issue of alternating the squares. The problem is that on larger screens some of the squares need to switch positions.

Taking a mobile first approach, I’ll start with the alternating stacked divs. The html structure and css will look as follows:

<div class="container">
  <div class="block">
    <div class="square">text</div>
    <div class="square picture">picture</div>
  </div>
  <div class="block">
    <div class="square">text</div>
    <div class="square picture">picture</div>
  </div>
  <div class="block">
    <div class="square">text</div>
    <div class="square picture">picture</div>
  </div>
</div>
.container {
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
}

.square {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
  padding-top: 5rem;
  padding-bottom: 5rem;
}

.picture {
  background-color: darkseagreen;
}

Which will look something like this on smaller screens:

text
picture
text
picture
text
picture

Now I can add the media query for larger screens that’ll switch the element to a two column grid:

...

@media (min-width: 768px) {
  .block {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}
text
picture
text
picture
text
picture

The issue is easier to see now. The second row’s picture element and text element are in the wrong position for the checkerboard. They need to be switched. But, I couldn’t figure out an easy way to reverse element order with css grid.

At this point I decided it was time to look at the SavvyCal source code and see how they implemented this. In the back of my mind I figured that if it wasn’t done using grid than it’s probably flexbox. I was right.

Instead of creating a grid for each row, they’re instead creating a flexbox container. Then, strategically adding flex-direction: row-reverse; and justify-content: flex-end; on the rows where the items needed to switch positions to form the checkerboard. The latter property ensures that the picture item doesn’t push all the way to the right when row-reverse is applied.

Without justify-content: flex-end;:

text
picture
text
picture
text
picture

With justify-content: flex-end;:

text
picture
text
picture
text
picture

I decided that the easiest way to apply the reverse styles would be to create a helper selector that I can apply as needed to various rows. This selector will only be used on larger screens, so I’ll create it in the media query.

...

@media (min-width: 768px) {
  .reversed {
    flex-direction: row-reverse;
    justify-content: flex-end;
  }
}
<div class="container">
  ...
  <div class="block reversed">
    <div class="square">text</div>
    <div class="square picture">picture</div>
  </div>
  ...
</div>

The next steps with this element would be add actual images and text like SavvyCal have done. Their implementation is really nice. Actually, there are a lot of elements on their landing page that are well designed. I like that their html and css source code aren’t super complicated.

They’re using Tailwindcss so it was tricky to unwind their css since it’s all utility class based, but it wasn’t terrible. I sort of know what I’m looking for now when it comes to reverse engineering tailwind utility classes. It just takes practice.

Conclusion & final code

I’d use this element. I’m seeing it all over the place now. It seems like the folks at Tailwind have start to make it more popular, so I’m sure I’ll be seeing it more and more.

Final code
/* styles.css */
.container {
  max-width: 1280px;
  margin-left: auto;
  margin-right: auto;
}

.square {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
  padding-top: 5rem;
  padding-bottom: 5rem;
}

.picture {
  background-color: darkseagreen;
}

@media (min-width: 768px) {
  .block {
    display: flex;
  }

  .reversed {
    flex-direction: row-reverse;
    justify-content: flex-end;
  }

  .square {
    width: 50%;
    padding-top: 9rem;
    padding-bottom: 9rem;
  }
}
<!-- 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>Checkerboard element demo</title>
</head>

<body>
  <main>
    <div class="container">
      <div class="block">
        <div class="square">text</div>
        <div class="square picture">picture</div>
      </div>
      <div class="block reversed">
        <div class="square">text</div>
        <div class="square picture">picture</div>
      </div>
      <div class="block">
        <div class="square">text</div>
        <div class="square picture">picture</div>
      </div>
    </div>
  </main>
</body>

</html>