Niels Leenheer's cssDOOM Brings Everyone's Favorite 1993 FPS Game to Cascading Style Sheets (CSS)
Play id Software's classic in-browser like never before — thanks to a rendering engine that (ab)uses CSS features.
Niels Leenheer has ported id Software's classic first-person shooter Doom to an unexpected platform: Cascading Style Sheets (CSS), normally used to control the layout and appearance of modern web pages.
"CSS is Doomed," Leenheer says of the project. "No, CSS is awesome. CSS is better than ever and it is only getting better. And that is why I built Doom in CSS. Every wall, floor, barrel, and imp is a <div>, positioned in 3D space using CSS transforms. The game logic runs in JavaScript, but the rendering is entirely CSS. You can play it right now. Why? Because I wanted to find the limits of what a browser can do. See how powerful modern CSS is. And because it’s Doom. In CSS. Do you really need more of a reason?"
First released in 1993 to critical acclaim, Doom originally required a fairly powerful desktop PC — but the march of technology means it has since been ported to platforms including thermostats, GPS receivers, and the low-cost Raspberry Pi Pico microcontroller platform, aided in no small part by id Software's decision to release the source code for earlier game engines when it makes the move to a new one.
cssDOOM takes the original game and makes it playable in-browser, using Cascading Style Sheets (CSS) for the rendering — though the game logic runs in the background in JavaScript, still in-browser. "We use the same data the original Doom engine uses: vertices, linedefs, sidedefs and sectors, all extracted from the original WAD file that came with the shareware version of the game back in 1993," Leenheer explains. "And with this data we create a static scene out of a couple thousand <div> elements and let the browser do all of the hard work.
"I don’t have any experience with rendering in 3D. And what I remembered from the few times that I used 3D modeling software was that you have a camera, that you can move and animate. But CSS doesn’t have a camera. So we do a trick: we move the entire world in the opposite direction of the player. We move the world around the player. Which turns out to be one of the classic tricks of how this is done."
The CSS port of Doom comes hot on the heels of further proof of the Turing-completeness of CSS: the release of x86CSS, an Intel x86 PC emulator written by Lyra Rebane — and which, unlike the CSS Doom port, requires no JavaScript. "Is this practical? Not really," the developer admitted at the time, "you can get way better performance by writing code in CSS directly rather than emulating an entire archaic CPU architecture. It is fun though, and computers are made for art and fun!"
It's also arguably not the strangest Doom port we've seen of late: earlier this month Adam Rice made the game available via Domain Name Service (DNS) queries, taking up around 2,000 TXT records to distribute the shareware version of the game — though DNS is only used as a file storage and transfer medium, with the game being executed otherwise-traditionally on the PC requesting it.
"It works way better than I ever expected," Leenheer says of cssDOOM. "But of course, it won’t replace a proper WebGL or WebGPU renderer. Performance is limited. But that’s not the point. This is about pushing the boundaries of what CSS can do. Trig functions, @property animations, clip-path, SVG filters, anchor positioning — these are all production-ready CSS features being used in ways their spec authors probably never imagined."
More information is available in Leenheer's blog post, while full source code is available on GitHub under the reciprocal GNU General Public License 2; a playable version is available on cssdoom.wtf.