Have you ever explored the power of grid-auto-flow: dense
? When combined with randomly generated values (constrained within a set range), you can use grid-column
and grid-row
properties to create cool, grid-based art. Let’s dive in!
First, let’s create a base grid structure:
main {
display: grid;
grid-auto-flow: dense;
grid-template-columns: repeat(auto-fill,
minmax(var(--w, 4cqi), 1fr));
}
-
display: grid
: Establishes a CSS grid layout. -
grid-auto-flow: dense
: Automatically fills gaps in the grid by repositioning items to minimize empty spaces. -
grid-template-columns
: Defines a responsive column layout. Here, columns are created automatically to fill the available space (auto-fill
), each with a minimum width of--w
(defaulting to4cqi
) and a maximum width of1fr
.
At this point, --w
is undefined, so the default value (4cqi
) is used. Here’s what the initial grid looks like:
Next, we’ll fill the grid with a bunch of <b>
-nodes. As we render these with JavaScript, we add 2 variables per node:
-
--gc
: Number of columns to span. -
--gr
: Number of rows to span.
Here’s how we generate random values in JavaScript:
const random = (min, max) =>
Math.random() * (max - min) + min
const column = () =>
`--gc:${Math.floor(random(0, 4))};`
const row = () =>
`--gr:${Math.floor(random(0, 3))};`
In CSS, we apply these custom properties:
b {
background: oklch(var(--l) var(--c) var(--h) / var(--a));
grid-column: span var(--gc);
grid-row: span var(--gr, 1);
}
Let’s also add some random colors in oklch
, using a small helper method:
const color = () => `--l:${
random(0, 100)}%;--c:${
random(0, 0.5)};--h:${
random(0, 60)};--a:${
random(0.2, 1)};`
Now we get:
Thank you, grid-auto-flow: dense
!
To make things more dynamic, let’s add transformations like rotation and scaling:
b {
rotate: var(--r);
scale: var(--s);
}
In JavaScript, we generate random transformation values:
const transform = () =>
`--r:${random(-2, 3)}deg;
--s:${random(0.8, 1.2)};`
Let’s check it out:
Fancy! Now, to take it up a notch, let’s add some cool SVG filters.
In JavaScript, we add another small helper method to pick a random filter per <b>
-node:
const filter = () =>
`--url:url(#${
[
"pencilTexture",
"pencilTexture2",
"pencilTexture3",
"pencilTexture4",
][Math.floor(random(0, 4))]
});`
This gives us:
Now, by simply adjusting the --w
property and the number of elements, we can generate vastly different artworks:
Or:
We can also adjust the start- and stop values in the color method:
Demo
Here’s a Codepen demo. I've added controls below the artwork, so you can easily tweak the properties:
Top comments (6)
This is quite an interesting thing to play around with. Imagine you are creating a detective game and you want to have such a scene where you have a pec board with all the evidence and pictures, you can make them in this way.
Thanks for the write up.
Thanks, and great idea with the board!
I had a lot of fun playing with the sliders I must say!
Now I just need a "quirky / playful" project to work on so I can steal it and use it! haha.
Maybe a detective game, as Ravin suggested?
Thank you for including pictures! XD this is cool.
Thank you!