DEV Community

Cover image for The CarnEvil of Horrors
Wil McGill
Wil McGill

Posted on

The CarnEvil of Horrors

Frontend Challenge Perfect Landing Submission 🦇🎃

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.

1st section of landing

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;
}

Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

2nd section of landing

3rd section of landing

@keyframes drip {
    0% { opacity: 0; height: 0; top: 0; }
    10% { opacity: 1; }
    100% { opacity: 0; height: 100px; top: 100%; }
}
Enter fullscreen mode Exit fullscreen mode

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);
}

Enter fullscreen mode Exit fullscreen mode

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); }
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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)