# How to create a Grid of squares

# The problem

You want to display items side by side in a grid. You set the number of columns, and you want each item's height to match its width to form a square. How do you do this?

I faced this problem at work. I needed to create a gallery like on iPhone, WhatsApp, or Telegram, where you see a grid of images and can click on them to view in full screen.

# Achieve equal width

To achieve the items having equal width, we can use display Grid.

```xml
<div className="grid grid-cols-4 gap-1">
  {images &&
    images.map((image) => (
      <img key={image.id} src={image.url} alt="image" className="w-full" />
    ))}
</div>
```

This will give us a grid of 4 columns with a gap of 4px. Each column will take equal width. The images will take the full width of the column and their height will adjust to maintain the aspect ratio.

The issue here is that we want the images to take equal height. Once that's done, we could use `object-fit: cover;` to ensure the images cover the entire space and their aspect ratio is maintained.

# Achieve equal height

To make height the same value as the width, we can use `padding-top: 100%;` to achieve this. When you use padding with percentage, it's calculated based on the width of the element.

```xml
<div className="grid grid-cols-4 gap-1">
  {images &&
    images.map((image) => (
      <div
        // padding top 100% to ensure square based off the width
        className="relative w-full pt-[100%]"
        key={image.id}
      >
        <img
          src={image.url}
          alt=""
          className="absolute left-0 top-0 h-full w-full object-cover"
        />
      </div>
    ))}
</div>
```

As you can see, we now have a wrapper around the image.

Let's try to understand how things work here in chronological order:

1. `div` is the wrapper. It takes full width and its height is the same as the width.
    
2. `div` has `padding-top: 100%;`. This means it will naturally push down the image inside of it to fill the space.
    
3. Therefore, the image can not be inside the normal flow of the document.
    
4. `div` is given relative positioning.
    
5. `img` is given absolute positioning and can be placed anywhere.
    
6. Because the parent of `img` has relative positioning, the `img` will be positioned relative to its closest ancestor that has relative or absolute positioning.
    
7. `img` is given `left: 0; top: 0;`. This means the top left corner of the image will be at the top left corner of the `div`.
    
8. `img` is given `h-full w-full`. This means the image will take the full height and width of the `div`.
    
9. `img` is given `object-cover`. This means the image will cover the entire space of the `div` and its aspect ratio is maintained.
    

And that's how you achieve a grid of squares.
