DEV Community

Andrew McCallum
Andrew McCallum

Posted on

A grid layout with responsive squares

With the advent of flex-box and grid it is now easier than every to create a nice, clean grid layout. But the question is, what should I use and how can I make it responsive?

Suppose I have the following HTML and want each square inside my grid to have equal proportions, even as the screen size changes.

<div class="square-container">

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content">
    </div>
  </div>

</div>
Enter fullscreen mode Exit fullscreen mode

Lucky for us we can use either flex-box or grid to create a grid container and keep the width of each square equal. We can then use a little trick with padding-top: 100%; which will keep our square height the same as our width.

First up, our flex example:

.square-container {
  display: flex;
  flex-wrap: wrap;
}

.square {
  position: relative;
  flex-basis: calc(25% - 10px);
  margin: 5px;
  border: 1px solid;
  box-sizing: border-box;
}

.square::before {
  content: '';
  display: block;
  padding-top: 100%;
}

.square .content {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

We end up with something like this:

alt text

By adding .square::before we are essentially adding an inner element to our square which has the same height as the parent squares width thanks to our little padding-top: 100%; trick. We can then position our square content over the top of this inner element and it will be a perfect square.

Similarly if you'd like to use grid to acheive the same thing, you can do something like this:

.square-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
  grid-gap: 10px;
}

.square {
  position: relative;
  border: 1px solid;
  box-sizing: border-box;
}

.square::before {
  content: '';
  display: block;
  padding-top: 100%;
}

.square .content {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Hopefully by combining either flex-box or grid with the padding-top trick, you too can create grid layouts with responsive squares.

Discussion (2)

Collapse
afif profile image
Temani Afif

now you can safely use aspect-ratio: jsfiddle.net/6rwc2q5u/ it has a good support everywhere: caniuse.com/mdn-css_properties_asp... (and soon available on Safari)

Collapse
stretch0 profile image
Andrew McCallum Author

Ah nice, that's quick and simple