🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)
🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)

🔧 Programmierung 🕛 kürzlich 7 Min Lesezeit
0

Haunted Loop: A Pure-CSS Halloween Scene

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




👻 Haunted Loop: A Pure-CSS Halloween Scene



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






Inspiration



I wanted a looping “mini-horror short” built only with CSS: a crescent moon drifts, a witch flies past, a ghost peeks from a window, bats swarm, and a neon “ENTER” sign flickers like a haunted arcade. The whole thing is a nod to old-school 8-bit spooky intros — minimal shapes, big vibes.






Demo



Paste this into CodePen (HTML panel) or save as a single .html file and open in your browser. It’s pure CSS (no images, no JavaScript).




CODE
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Haunted Loop — Pure CSS Halloween</title>
<style>
:root{
--bg:#0a0b10;
--sky1:#0b0f1c;
--sky2:#121a30;
--moon:#ffd68a;
--house:#0e0f14;
--window:#f0f6ff;
--ghost:#f8fbff;
--accent:#7c9bff;
--neon:#ff5a8a;
--fog:#a8b1ff1a;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
margin:0; background: radial-gradient(120% 120% at 50% 10%, var(--sky2), var(--bg) 70%);
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial;
color:#cfd6ff; display:grid; place-items:center;
}

.scene{
width:min(92vw, 840px); aspect-ratio:16/9; position:relative;
border-radius:18px; overflow:hidden; background:
radial-gradient(120% 140% at 50% -10%, var(--sky1), transparent 60%),
linear-gradient(var(--bg), var(--bg));
box-shadow: 0 20px 60px #0008, inset 0 0 0 1px #ffffff0f;
isolation:isolate;
}

/* Moon */
.moon{
position:absolute; top:6%; left:10%;
width:86px; height:86px; border-radius:50%;
background:radial-gradient(65% 65% at 35% 35%, #fff4cc, var(--moon) 55%, #eabf6a 66%, #0000 67%);
box-shadow:0 0 24px 6px #ffd68a55, 0 0 120px 18px #ffd68a22;
animation: drift 18s linear infinite;
}
.moon::after{
content:""; position:absolute; inset:0;
background: radial-gradient(40% 40% at 65% 45%, #0000 45%, #000 46% 100%);
border-radius:50%; transform: translateX(8px);
mix-blend-mode:multiply; opacity:.25;
}
@keyframes drift{ 0%{transform:translateX(0)} 100%{transform:translateX(22vw)} }

/* Stars */
.stars, .stars::before, .stars::after{
position:absolute; inset:0; content:""; background:
radial-gradient(2px 2px at 10% 20%, #fff8 98%, #0000) 0 0/15% 15%,
radial-gradient(1.5px 1.5px at 40% 60%, #fff6 98%, #0000) 0 0/22% 22%,
radial-gradient(1.5px 1.5px at 85% 30%, #fff7 98%, #0000) 0 0/18% 18%;
opacity:.5; filter:saturate(130%);
}
.stars{opacity:.35}
.stars::before{opacity:.4; transform:translateY(2px)}
.stars::after{opacity:.25; transform:translateY(-2px)}

/* Ground silhouette */
.ground{
position:absolute; left:-5%; right:-5%; bottom:-2%;
height:38%; background:
radial-gradient(120% 120% at 50% -10%, #0000 65%, #000 66%),
linear-gradient(#0b0c12, #07080e);
clip-path: polygon(0 40%, 15% 45%, 22% 43%, 30% 48%, 40% 46%, 48% 50%, 62% 42%, 73% 47%, 83% 45%, 100% 40%, 100% 100%, 0 100%);
filter: drop-shadow(0 -8px 16px #000c);
}

/* House */
.house{
position:absolute; bottom:14%; left:50%; transform:translateX(-50%);
width:min(50%, 420px); height:48%;
}
.house .body{
position:absolute; bottom:0; left:8%; right:8%; height:68%;
background: linear-gradient(#0d0f17, #090b12);
box-shadow: inset 0 0 0 1px #ffffff08;
}
.roof{
position:absolute; bottom:68%; left:4%; right:4%; height:22%;
background: linear-gradient(#0b0d15, #070910);
clip-path: polygon(0 100%, 50% 0, 100% 100%);
filter: drop-shadow(0 6px 0 #05060b);
}
.chimney{
position:absolute; bottom:78%; left:12%; width:6%; height:18%;
background:#0b0d14; box-shadow: inset 0 0 0 1px #ffffff10;
}

/* Windows */
.window{
--glow:#a6b9ff;
position:absolute; width:17%; height:22%;
background: radial-gradient(120% 120% at 20% 20%, #fff, var(--window) 55%, #9ab0ff 85%);
box-shadow:
0 0 12px 4px #a6b9ff33,
inset 0 0 0 2px #ffffff0f;
outline: 1px solid #ffffff12;
border-radius:2px; overflow:hidden;
}
.window.left{ left:16%; bottom:24% }
.window.right{ right:16%; bottom:24% }
.window.center{ left:50%; transform:translateX(-50%); bottom:48%; height:24% }

/* Ghost peeking in left window */
.window.left .ghost{
position:absolute; bottom:-6%; left:50%; transform:translateX(-50%);
width:64%; height:90%; border-radius:24px 24px 14px 14px;
background: radial-gradient(80% 100% at 50% 0%, var(--ghost), #e7ecff 65%, #0000 66%);
animation: peek 6s ease-in-out infinite;
}
.ghost::before, .ghost::after{
content:""; position:absolute; top:34%; width:11px; height:11px; border-radius:50%;
background:#0d1b2a; box-shadow: 0 0 0 2px #ffffff55 inset;
}
.ghost::before{ left:30% }
.ghost::after{ right:30% }
@keyframes peek{
0%, 100% { transform: translate(-50%, 0) }
40% { transform: translate(-50%, -14%) }
60% { transform: translate(-50%, -8%) }
}

/* Neon sign */
.sign{
position:absolute; right:8%; bottom:10%;
width:120px; height:48px; border-radius:6px;
background: #2a0b18; border:2px solid #3a1422;
display:grid; place-items:center; letter-spacing:1px;
color:#fff; font-weight:800; font-size:14px;
text-shadow:0 0 10px var(--neon), 0 0 22px var(--neon);
box-shadow: inset 0 0 12px 2px #000, 0 0 34px 6px #ff5a8a2f;
animation: flicker 3.2s steps(12) infinite;
}
@keyframes flicker{
0%, 4%, 8%, 12%, 100% { filter:brightness(1) saturate(1.2) }
2%, 6%, 10% { filter:brightness(.3) saturate(.6) }
}

/* Bats group */
.bat{
position:absolute; top:14%; left:-10%;
width:28px; height:12px; background:#0b0d14; border-radius:8px;
box-shadow:
-16px 0 0 0 #0b0d14,
16px 0 0 0 #0b0d14;
transform-origin:50% 50%;
animation: fly 10s linear infinite;
opacity:.85;
}
.bat::before, .bat::after{
content:""; position:absolute; top:-8px; width:18px; height:18px; border:2px solid #0b0d14; border-bottom-color:transparent; border-right-color:transparent;
border-radius: 0 0 0 100%;
}
.bat::before{ left:-18px; transform:rotate(-30deg) }
.bat::after{ right:-18px; transform: scaleX(-1) rotate(-30deg) }
.bat.b2{ top:22%; animation-duration: 12s; transform:scale(.9); opacity:.7 }
.bat.b3{ top:18%; animation-duration: 14s; transform:scale(1.1); opacity:.6 }
@keyframes fly{
0% { transform: translateX(0) translateY(0) rotate(0deg) }
25% { transform: translateX(25vw) translateY(-8px) rotate(3deg) }
50% { transform: translateX(50vw) translateY(4px) rotate(-2deg) }
75% { transform: translateX(75vw) translateY(-10px) rotate(2deg) }
100% { transform: translateX(105vw) translateY(0) rotate(0deg) }
}

/* Witch silhouette sweeping across the moon */
.witch{
position:absolute; top:10%; left:-12%; width:80px; height:18px;
background:#0b0d14; border-radius:3px;
box-shadow: 10px 6px 0 6px #0b0d14; /* body + skirt block */
transform-origin:50% 50%;
animation: sweep 12s ease-in-out infinite;
}
.witch::before{
content:""; position:absolute; left:8px; top:-10px; width:20px; height:20px; border-radius:50%; background:#0b0d14; /* head */
box-shadow: 14px 6px 0 2px #0b0d14; /* hat brim */
}
.witch::after{
content:""; position:absolute; left:-22px; top:8px; width:0; height:0; border-left:26px solid #0b0d14; border-top:6px solid transparent; border-bottom:6px solid transparent; /* broom */
}
@keyframes sweep{
0%{ transform: translateX(0) translateY(0) rotate(-2deg) }
45%{ transform: translateX(48vw) translateY(-6px) rotate(0deg) }
50%{ transform: translateX(52vw) translateY(-4px) rotate(1deg) }
100%{ transform: translateX(108vw) translateY(0) rotate(-1deg) }
}

/* Fog layers */
.fog,.fog::before,.fog::after{
position:absolute; left:-10%; right:-10%; bottom:10%;
height:22%; content:""; background:
radial-gradient(60% 100% at 20% 80%, var(--fog), transparent 70%),
radial-gradient(60% 100% at 70% 80%, var(--fog), transparent 70%);
filter: blur(6px);
animation: fog 18s linear infinite;
}
.fog::before{ animation-duration: 22s; transform:translateY(8px) scaleY(1.15) }
.fog::after { animation-duration: 26s; transform:translateY(-8px) scaleY(.9) }
@keyframes fog{
0%{ transform: translateX(0) }
100%{ transform: translateX(-12%) }
}

/* Accessibility */
.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
</style>
</head>
<body>
<div class="scene" role="img" aria-label="A haunted house at night with a crescent moon, bats, a flying witch, flickering neon sign, drifting fog, and a shy ghost in the window.">
<div class="stars"></div>
<div class="moon" aria-hidden="true"></div>
<div class="witch" aria-hidden="true"></div>
<div class="bat b1" aria-hidden="true"></div>
<div class="bat b2" aria-hidden="true"></div>
<div class="bat b3" aria-hidden="true"></div>
<div class="house" aria-hidden="true">
<div class="roof"></div>
<div class="chimney"></div>
<div class="body"></div>
<div class="window left"><div class="ghost"></div></div>
<div class="window center"></div>
<div class="window right"></div>
</div>
<div class="sign">ENTER</div>
<div class="ground"></div>
<div class="fog" aria-hidden="true"></div>
<span class="sr-only">Looping animation; no flashing above WCAG thresholds.</span>
</div>
</body>
</html>






Embed on DEV:

If you prefer CodePen embed, create a Pen with that HTML and add to the post as:

{% codepen https://codepen.io/<your-user>/pen/<id> %}






Journey





  • Constraints as style: I limited myself to shapes via gradients, borders, and box-shadows (no images, no SVGs).


  • Motion grammar: Each element animates with a distinct “character” — the witch sweeps (ease-in-out), bats flutter (linear with slight y-jitter), the neon sign flickers (stepped).


  • Accessibility: The scene has a descriptive aria-label, a screen-reader note, and flicker stays under common seizure thresholds (short bursts, low duty cycle).


  • Performance: No JS, no external assets; it’s all GPU-friendly transforms/opacity. It runs smoothly on mobile.






What I’d do next




  • Add a “parallax scroll” variant with CSS perspective.

  • Create a color-scheme switcher (pumpkin / toxic green / midnight cyan) using @media (prefers-color-scheme) and custom properties.

  • Build a “scene editor” UI that lets people tweak moon size, sign text, fog density — then exports a static CSS art snapshot.









License



MIT. Credit is appreciated but not required — remix away.






Team



Solo submission — Peace Thabiwa (Botswana) — concept builder, BINFLOW/Web4 enthusiast.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Hackers Just Poisoned the Rust Supply Chain | Threat Wire
1 Quelle
Hackers Found a Way Into Humanoid Robots | Threat Wire
1 Quelle
Bits und so #1021 (Passwort für Laufwerk)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Haunted Loop: A Pure-CSS Halloween Scene

Thematisch verwandte Begriffe: Haunted, Loop, PureCSS, Halloween · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...