Joined Dev.to literally yesterday, and one of the first things I came across was this Halloween challenge, and I immediately said "cool". I've been messing around with web development for a while now, so figured I'll try it, why not? I built "The CarnEvil of Horrors". It's based on one of my favorite childhood book series, Goosebumps, the landing page taking direct inspiration from the Give Yourself Goosebumps series - "Escape from the Carnival of Horrors", by R.L Stine. It's a book I still have in my collection today.
The tech stack I used was HTML, CSS, and vanilla JS.
Check out the site: https://afkjr.github.io/CarnEvil-of-Horrors/
The CarnEvil of Horrors is a responsive single-page site with three sections (About, Scares, Tickets) that features smooth scrolling navigation, unique horror-themed styling for each section, and a bit of JavaScript effects.
I found a carnival interior image from Freepik.com (royalty-free) and created three distinct themes using CSS custom properties:
:root {
--color-blood-red: #8b0000;
--color-toxic-green: #39ff14;
--color-shadow-purple: #4a0e4e;
--transition-speed: 0.3s;
}
For the background, I implemented an overlay to darken the image for readability:
body {
background-image:
linear-gradient(
rgba(5, 2, 0, 0.7),
rgba(5, 2, 0, 0.7)
),
url('IMG_0473.jpg');
background-attachment: fixed;
}
I created animated blood drips using CSS animations and JavaScript. The CSS defined the drip animation:
.blood-drip {
position: absolute;
width: 2px;
background: linear-gradient(to bottom, var(--color-blood-red), transparent);
animation: drip 3s linear infinite;
}
@keyframes drip {
0% { opacity: 0; height: 0; top: 0; }
10% { opacity: 1; }
100% { opacity: 0; height: 100px; top: 100%; }
}
The JavaScript dynamically creates drips at random positions:
function createBloodDrip() {
const bloodContainer = document.getElementById('bloodDripsContainer');
const drip = document.createElement('div');
drip.className = 'blood-drip';
drip.style.left = Math.random() * 100 + '%';
bloodContainer.appendChild(drip);
setTimeout(() => drip.remove(), 3000);
}
For the glitch effect on titles, I created CSS animations with pseudo-elements:
.glitch.active::before {
content: attr(data-text);
animation: glitch-1 0.3s both infinite;
color: var(--color-toxic-green);
}
@keyframes glitch-1 {
0% { transform: translateX(0); }
20% { transform: translateX(-2px); }
40% { transform: translateX(2px); }
}
JavaScript triggers the effect randomly:
function triggerGlitchEffect(element) {
element.classList.add('active');
setTimeout(() => element.classList.remove('active'), 300);
}
function startRandomGlitch() {
const glitchElements = document.querySelectorAll('.glitch');
setInterval(() => {
const randomElement = glitchElements[Math.floor(Math.random() * glitchElements.length)];
triggerGlitchEffect(randomElement);
}, 8000);
}
This was a fun project. My favorite challenges I faced were getting the blood drops to flow properly and the shaking effect when a user hovers over a ride (scares). This project also reinforced my learning in that:
- File Paths Matter: Always use forward slashes or relative paths in CSS
- Syntax is Critical: A single missing comma can break an entire effect
- CSS and JS Must Align: JavaScript effects require corresponding CSS animations developed together
- Incremental Testing: Test each feature as you build to catch issues immediately
- CSS Custom Properties are Powerful: Variables make adjustments quick and consistent



Top comments (0)