DEV Community

Cover image for The Friendly Floating Ghost
Abu Sofian
Abu Sofian

Posted on

The Friendly Floating Ghost

Frontend Challenge CSS Art Submission 🦇🎃

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

👻 The Friendly Floating Ghost.
Hello, Everyone! Here is my submission for the CSS Art: Halloween Challenge.
I wanted to create a design that was clean, simple, and captured a classic Halloween spirit. This is my "Friendly Floating Ghost," created entirely with HTML and CSS.
You can view the live demo here: https://codepen.io/abusofianid/pen/LEGgLpb

Key Features & CSS Techniques
My main goal was to bring the ghost to life using only CSS animations.

  • Effective Use of CSS (Animation):
    • Main Float Effect: The ghost's entire body gently floats up and down using a @keyframes animation (float) with ease-in-out timing for a smooth, spooky hover effect.
    • Dynamic Wavy Bottom: The "tail" of the ghost isn't just one static shape. It's made of four separate div elements. Each one has its own wave animation, but I used animation-delay on them at different intervals. This makes them bob up and down unevenly, creating a much more fluid and realistic "waving" motion.
  • Creativity & Aesthetic (The Shape):
    • The ghost's shape is built using border-radius in different ways: a large value creates the perfectly round head, while a different border-radius setting on the mouth creates the simple, hollow "O" shape.
    • The design is intentionally minimal and uses high contrast (a white ghost on a dark purple background) for a clean and clear aesthetic outcome. I had a lot of fun on this challenge and focused on making the CSS animations the star of the show. I hope you enjoy it! Complete Code (HTML + CSS) Here is the complete code. You can copy and paste this into a single file (e.g., ghost.html) and open it in any browser.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Floating Ghost</title>
    <style>
        /* Scene Setup */
        body {
            background-color: #0d001a; /* Very dark purple */
            display: grid;
            place-items: center;
            min-height: 100vh;
            margin: 0;
            overflow: hidden;
        }

        /* Ghost Body */
        .ghost {
            position: relative;
            width: 150px;
            height: 200px;
            background-color: #f0f0f0; /* Off-white */

            /* Creates the rounded head */
            border-radius: 75px 75px 0 0;

            /* Adds the floating animation */
            animation: float 3s ease-in-out infinite;

            /* Shadow for a slight 3D effect */
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }

        /* Ghost Eyes */
        .ghost-eyes {
            position: absolute;
            top: 60px;
            width: 100%;
            display: flex;
            justify-content: space-around;
        }

        .eye {
            width: 25px;
            height: 25px;
            background-color: #222;
            border-radius: 50%;
        }

        /* Ghost Mouth */
        .ghost-mouth {
            position: absolute;
            top: 100px;
            left: 50%;
            transform: translateX(-50%);
            width: 40px;
            height: 20px;
            background-color: #222;
            border-radius: 0 0 20px 20px; /* Inverted half-circle */
        }

        /* Wavy Ghost Bottom */
        .ghost-bottom {
            position: absolute;
            bottom: -20px; /* Sits just below the main body */
            left: 0;
            width: 100%;
            display: flex;
        }

        .ghost-bottom .wave {
            width: 25%; /* 4 waves */
            height: 20px;
            background-color: #f0f0f0;
            border-radius: 0 0 15px 15px; /* Half-circle */

            /* Animates the bottom wave */
            animation: wave 1s ease-in-out infinite alternate;
        }

        /* Stagger the animation delays so they don't move together */
        .ghost-bottom .wave:nth-child(2) {
            animation-delay: 0.2s;
        }
        .ghost-bottom .wave:nth-child(3) {
            animation-delay: 0.4s;
        }
        .ghost-bottom .wave:nth-child(4) {
            animation-delay: 0.6s;
        }

        /* -- Keyframe Animations -- */

        /* Floating animation (up and down) */
        @keyframes float {
            0%, 100% {
                transform: translateY(0);
            }
            50% {
                transform: translateY(-20px); /* Moves up 20px */
            }
        }

        /* Waving animation for the bottom pieces */
        @keyframes wave {
            0% {
                transform: translateY(0);
            }
            100% {
                transform: translateY(-8px); /* Moves up and down slightly */
            }
        }

    </style>
</head>
<body>

    <div class="ghost">
        <div class="ghost-eyes">
            <div class="eye"></div>
            <div class="eye"></div>
        </div>
        <div class="ghost-mouth"></div>

        <div class="ghost-bottom">
            <div class="wave"></div>
            <div class="wave"></div>
            <div class="wave"></div>
            <div class="wave"></div>
        </div>
    </div>

</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)