2

I want to create a grid of equal squares. I've been looking at CSS Grid as I thought it was possible to create equal width and height areas in grids. But I don't see anything in the Grid spec about it. The basic code is like this:

.squaregrid {
  max-width: 600px;
  margin: 20px;
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  grid-gap: 10px;
}

.cell {
  background: #ddd;
  font-size: 2em;
}
<div class="squaregrid">
  <div class="cell">A</div>
  <div class="cell">B</div>
  <div class="cell">C</div>
  <div class="cell">D</div>
  <div class="cell">E</div>
  <div class="cell">F</div>
  <div class="cell">G</div>
  <div class="cell">H</div>
  <div class="cell">I</div>
</div>

I get a 3x3 grid but the height of each "cell" is just the size of the letters (because the fr unit makes the rows' height relative to each other, not relative to the column width).

I can use a fixed size instead of 1fr but then of course it's not responsive.

I'm aware of the padding-bottom trick which is used to maintain an aspect ratio, but that involves multiple wrappers for every cell, plus if I'm doing that there's not really any need to use Grid, I can use regular divs or flexbox.

Any other solutions out there?

Answers on the "duplicate" question do not solve the problem.

DisgruntledGoat
  • 70,219
  • 68
  • 205
  • 290
  • Are you completely against JS? Would be pretty simple to accomplish that way... – Dryden Long Feb 08 '18 at 18:25
  • The latest news on this: https://cssence.com/code/2018-01-21-maintaining-aspect-ratio-with-css-grid You'll need a wrapper element no matter which approach you choose. – Sphinxxx Feb 10 '18 at 00:03

2 Answers2

3

I get a 3x3 grid but the height of each "cell" is just the size of the letters (because the fr unit makes the rows' height relative to each other, not relative to the column width).

When you say this...

grid-template: repeat(3, 1fr) / repeat(3, 1fr);

which is a shorthand for this...

grid-template-rows: 1fr 1fr 1fr
grid-template-columns: 1fr 1fr 1fr
grid-template-areas: none

you're creating a 3x3 grid where columns and rows take an equal distribution of free space.

But you want all cells to be square.

Unless the container has the exact same dimensions, the cells cannot be square using fr units.

You've set a maximum width to the container (max-width: 600px), but have no defined height. Therefore, expect to see rectangular cells.

If you want squares, try something like this:

.squaregrid {
    width: 400px;
    height: 400px;
    margin: 20px;
    display: grid;
    grid-template: repeat(3, 1fr) / repeat(3, 1fr);
    grid-gap: 10px;
}
.cell {
    background: #ddd;
    font-size: 2em;
}
<div class="squaregrid">
    <div class="cell">A</div>
    <div class="cell">B</div>
    <div class="cell">C</div>
    <div class="cell">D</div>
    <div class="cell">E</div>
    <div class="cell">F</div>
    <div class="cell">G</div>
    <div class="cell">H</div>
    <div class="cell">I</div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

You can use vw units to make it responsive. Instead of 1fr use 30vw like so:

.squaregrid {
    max-width: 600px;
    margin: 20px;
    display: grid;
    grid-template: repeat(3, 30vw) / repeat(3, 30vw);
    grid-gap: 10px;
}
.cell {
    background: #ddd;
    font-size: 2em;
}
<div class="squaregrid">
    <div class="cell">A</div>
    <div class="cell">B</div>
    <div class="cell">C</div>
    <div class="cell">D</div>
    <div class="cell">E</div>
    <div class="cell">F</div>
    <div class="cell">G</div>
    <div class="cell">H</div>
    <div class="cell">I</div>
</div>
Dryden Long
  • 10,072
  • 2
  • 35
  • 47