This article utilizes React, but the techniques are frontend-agnostic.
While working on a recent project, I needed to implement a CMS for an image gallery. In this gallery, multiple images may belong to the same item on display. I wireframed a handful of ideas, ultimately deciding that a compact layout, styled after the gallery itself, would be best. To achieve this, I turned to mathematics to create dynamic, fractal image grids within constant-sized containers.
To begin with, I created a standard grid to hold my cards. A dissection of CSS Grid is beyond the scope of this article, but a functional component follows.
- First, the FractalGrid.js component. To begin with, our cards will be void of content. For later use, I have included several image urls randomly selected from Unsplash.com.
- Next, FractalGrid.css handles the styling.
We now have a functional grid of empty cards.
Our goal is to dynamically fill each card with a varying number of images in a consistent pattern. To fit them, we’ll need to shrink the images based on the total number present. How do we approach this? I began with pencil and paper.
Let’s clean that up and map out the relationships.
Though there are different bases, we can see that the properties of our grids share a common exponent based on the number of images present. We can calculate this common exponent by taking the log₄ of the number of images and rounding up. For example:
- log₄(13 images) === 1.85, which rounds up to 2. Thus we will have 2² grid cells per side.
- log₄(27 images) === 2.37, which rounds up to 3. Thus we will have 2³ grid cells per side.
We now have all the information we need to dynamically adjust our grid.
First, we handle the width of the cells. We know how many columns we will need based on how many cells-per-side we’ve calculated
We could similarly use grid-template-rows to set our rows, but this will create empty rows that will affect vertical alignment. Instead, we can use grid-auto-rows and distribute the fractional value across our cells-per-side.
All that remains is to add our images; and with that, we have a functioning, fractal grid.
If we aren’t concerned with maintaining aspect ratios, and we’d instead prefer to fill the available space, we can set grid-auto-rows to 1fr.
A fully functioning repository of the code in this article may be found at
A demonstration of the originating project may be viewed here: