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>
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%;
}
We end up with something like this:
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%;
}
Hopefully by combining either flex-box or grid with the padding-top trick, you too can create grid layouts with responsive squares.
              
    
Top comments (2)
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)
Ah nice, that's quick and simple