This is a submission for Frontend Challenge - Halloween Edition, CSS Art._
Hey everyone! As the clock winds down on the Dev.to Frontend Challenge - Halloween Edition, I wanted to share my journey in creating a spooky, yet charming, Halloween scene purely with HTML and CSS. It's been a wild ride, a mix of pure frustration, "aha!" moments, and a lot of box-shadow tweaking.
I was inspired to create a "paper cutout" style halloween scene with layered elements, subtle shadows, and the vibrant yet muted color palette. I loved creating the central castle, the glowing pumpkin, the mischievous cat, and especially the creepy reaper on the right. My goal was clear: create this entire scene, capturing that papercraft feel, using only HTML and CSS. No img tags, no external assets – just pure code.
The image is made to be viewed in full screen on a Desktop, so please check it on a desktop.
This is my first submission for any Dev Challenge. I am a newbie at CSS art so the first step was to go through different CSS arts on Codepen and Google search and take some elements from them.
Here's a little peek into my journey, the (many) challenges I faced, and how I brought this haunted castle to life.
Every good scene needs a backdrop. I started simple:
The Sky: A linear-gradient from a dark navy to a deep purple.
The Ground: A simple, dark shape at the bottom.
The Moon: A radial-gradient for the color, border-radius: 50% for the shape, and a box-shadow for that eerie glow. The "glow" itself is animated to pulse gently.
The first real beast was the castle. This wasn't one div. This was a monster of position: absolute, z-index, and pseudo-elements.
The Structure: I built it piece by piece. A main body (.castle-main)and three towers (.castle-tower).
The Challenge: The z-index! For a while, my center tower was behind the main building, and the bridge was floating in the sky. It took a lot of tweaking to get the layers right so everything sat perfectly on the ground line.
The Details: The battlements (the tooth-like things on top) aren't individual divs. That would be a nightmare. Instead, I used a repeating-linear-gradient on a pseudo-element (::before) to create the pattern. The windows use a flickering animation on their opacity and box-shadow to look like candlelight.
With the set built, I needed to populate it.
First up: the Jack-o'-Lantern. This was fun! The body is a radial-gradient and a funky border-radius to make it squat. The face elements are simple clip-path triangles, but the mouth was a cool trick. To get the "stitched" look with teeth, I used a repeating-linear-gradient on the ::after pseudo-element of the mouth div.
Next, the Grim Reaper. This is one of my favorite parts.
clip-path: polygon(...). I just clicked out the points to create that flowy, tattered robe shape..reaper-eyes div, with a box-shadow animation to make them pulse.A static scene is boring. I wanted movement everywhere. This was the biggest challenge: orchestrating chaos.
.bat-wing-left, .bat-wing-right) have their own flap animation. I used animation-delay on the main .bat divs to make them fly out at different times.This project was a beast, but I'm so proud of the result. My biggest takeaways:
Pseudo-elements are your best friend. I built moon craters, pumpkin segments, reaper eyes, stems, and battlements all without adding a single extra div to the HTML. My HTML is super clean; my CSS file... less so. 😂
z-index is a dark art. When you have 20+ absolutely positioned elements, you will spend an hour trying to figure out why your cat is standing in front of a castle tower but behind a pumpkin.
animation-delay is key. Don't have everything happen at once. Staggering the bats, the window flickers, and the ghost's appearance makes the world feel more natural and less like a repetitive loop.
It was a ton of work, but seeing all the little pieces come together and move was one of the most satisfying coding moments I've had in a while.
Thanks for reading! What's your favorite part of the scene?