DEV Community

Cover image for CSS HALLOWEEN ART - by STEFAN DONOSA
Ștefan Donosă
Ștefan Donosă

Posted on

CSS HALLOWEEN ART - by STEFAN DONOSA

Frontend Challenge CSS Art Submission 🦇🎃

This is a submission for Frontend Challenge - Halloween Edition, CSS Art, by Stefan Donosa.

Inspiration

The inspiration behind this piece was the desire to create a "maximalist" Halloween scene, a single artboard that captures the entire essence of the holiday in one diorama. I wanted to move beyond a simple animation and build a complete, immersive digital painting using only CSS.

The central theme is a haunted cabin perched precariously on a hill, set against a supernatural, malevolent sky. The color palette of the sky (blue-violet-orange-red) and the stark, white spectral moon were the starting points for setting a tense and magical atmosphere.

I wanted the scene to feel "alive," so I integrated classic horror elements: an ancient graveyard, a vigilant black cat, ethereal ghosts, a sinisterly glowing Jack-o'-lantern, and the composition's centerpiece, a full skeleton rising from its grave. The addition of the River Styx in the corner was meant to ground the piece in a deeper mythology, hinting at a gateway between worlds.

Demo 

To see the painting in its full animated glory, please visit the live demo below:

Here

Journey 

This project was a monumental challenge in layering and detail management. The goal was to build a scene with incredible depth using exclusively HTML and CSS, with no JavaScript.

The process

It all started with a clear vision: a complete tableau. I built the scene layer by layer, starting from the background (z-index: 0) and working my way to the foreground (z-index: 30+). The primary challenge was ensuring every element was visible and interacted correctly. For example, the River Styx (.river-styx) had to flow "over" the grass field (.hill-bg), but the tombstones and skeleton had to sit "on" the grass, "next to" the river. This required meticulous z-index management.

What I learned

  • CSS texturing: To prevent elements from looking "empty" or "transparent" (an early problem), I used complex repeating-linear-gradient tricks to create a detailed brick-like texture for the cabin and a lush, dark grass effect for the unified ground.

  • Complex shape creation: The full skeleton is, by far, the element I am most proud of. It's built from dozens of divs and pseudo-elements (::before, ::after), each styled with border-radius and transform to create an articulated skull, spine, ribcage, and arms.

  • Atmosphere is everything: A static scene is boring. The real challenge was orchestrating the animations:

    1. Lightning (.lightning) uses a keyframes animation that triggers abruptly at long intervals.
    2. Rain (.rain-container-fg) is composed of 300 individual divs, each with a unique animation-delay, to create a dense and chaotic effect.
    3. Ghosts (.ghost) were intentionally scaled down (transform: scale(0.6)) and blurred (filter: blur(2px)) to make them feel more distant and ethereal.
    4. The Pumpkin was simplified; I removed all complex inset shadows in favor of a flat shape, where the flickering light of the carved face is the only light source.

Future hopes

While I'm incredibly proud of the final result (over 1200 lines of code), the next step would be to add interactivity. Perhaps a hover effect on the tombstones that makes the skeleton jolt, or a lightning flash triggered by a click. For now, it stands as a piece of pure, animated digital art.

Top comments (3)

Collapse
 
hashbyt profile image
Hashbyt

This is incredible CSS artistry the depth and atmosphere you've created with pure code is stunning. How did you manage the complexity of the z-index layering to keep everything perfectly positioned?

Collapse
 
stefan_donosa profile image
Ștefan Donosă

​Thank you so much for the incredible compliment! That's so kind of you to say. 🙏
​You've absolutely pinpointed the toughest part of the entire build! Managing the z-index complexity was a real journey, especially with over 1000 elements.
​My main strategy was to avoid "magic numbers" (like 1, 2, 3...) and instead think in layer groups.
​The background (sky, moon, distant stars) lived in the z-index: 0-10 block.
​The mid-ground (the cabin, background trees) was in the z-index: 11-20 block.
​The foreground (tombstones, skeleton, pumpkin, cat) got the z-index: 21-30 block.
​Finally, all the atmospherics (fog, rain, lightning) were layered on top with z-index: 30+.
​This "block" system made it much easier to slot new elements in without breaking everything. The most difficult negotiation was definitely the River Styx, the grass, and the skeleton. Getting the river (z-index: 21) to flow over the main grass field (z-index: 2), while ensuring the skeleton and tombstones (z-index: 22) sat on that grass, was a fun puzzle!
​I'm so glad you like how the depth and atmosphere turned out. Thanks again for the support!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.