For years, I thought drag-and-drop games, especially those with rotation, spatial logic, and puzzle-solving, were only possible with JavaScript. Then one day, I asked AI:
“Is it possible to build a fully interactive Tangram puzzle game using only CSS?”
The answer: “No — not really. You’ll need JavaScript.” That was all the motivation I needed to prove otherwise.
But first, let’s ask the obvious question: Why would anyone do this?
Well…
– To know how far CSS can be pushed in creating interactive UIs.
– To get better at my CSS skills.
– And it’s fun!
Fair enough?
Now, here’s the unsurprising truth: CSS isn’t exactly made for this. It’s not a logic language, and let’s be honest, it’s not particularly dynamic either. (Sure, we have CSS variables and some handy built-in functions now, hooray!)
In JavaScript, we naturally think in terms of functions, loops, conditions, objects, comparisons. We write logic, abstract things into methods, and eventually ship a bundle that the browser understands. And once it’s shipped? We rarely look at that final JavaScript bundle — we just focus on keeping it lean.
Now ask yourself: isn’t that exactly what Sass does for CSS?
Why should we hand-write endless lines of repetitive CSS when we can use mixins and functions to generate it — cleanly, efficiently, and without caring how many lines it takes, as long as the output is optimized?
So, we put it to the test and it turns out Sass can replace JavaScript, at least when it comes to low-level logic and puzzle behavior. With nothing but maps, mixins, functions, and a whole lot of math, we managed to bring our Tangram puzzle to life, no JavaScript required.
Let the (CSS-only) games begin! 🎉
The game consists of seven pieces: the classic Tangram set. Naturally, these pieces can be arranged into a perfect square (and many other shapes, too). But we need a bit more than just static pieces.
So here’s what I am building:
– A puzzle goal, which is the target shape the player has to recreate.
– A start button that shuffles all the pieces into a staging area.
– Each piece is clickable and interactive.
– The puzzle should let the user know when they get a piece wrong and also celebrate when they finish the puzzle.
I started by setting up the HTML structure, which is no small task, considering the number of elements involved.
– Each shape was given seven radio buttons. I chose radios over checkboxes to take advantage of their built-in exclusivity. Only one can be selected within the same group. This made it much easier to track which shape and state were currently active.
– The start button? Also a radio input. A checkbox could’ve worked too, but for the sake of consistency, I stuck with radios across the board.
– The puzzle map itself is just a plain old
– For rotation, we added eight radio buttons, each representing a 45-degree increment: 45°, 90°, 135°, all the way to 360°. These simulate rotation controls entirely in CSS.
– Every potential shadow position got its own radio button too. (Yes, it’s a lot, I know.)
– And to wrap it all up, I included a classic reset button inside a