Back to Components
Ghost 404 Page | Interactive Animated Error Screen with Floating Ghost and Eye Tracking
Component

Ghost 404 Page | Interactive Animated Error Screen with Floating Ghost and Eye Tracking

CodewithLord
October 4, 2025

The Ghost 404 Page is a creative and playful error page concept featuring a floating ghost that follows your mouse movements. Built using HTML, CSS, and JavaScript (with jQuery), it turns a simple “page not found” message into a delightful animated experience.

🧠 Description

The Ghost 404 Page is a creative and playful error page concept featuring a floating ghost that follows your mouse movements. Built using HTML, CSS, and JavaScript (with jQuery), it turns a simple “page not found” message into a delightful animated experience. The ghost gently bounces in the air with glowing effects, its eyes track the user’s cursor, and subtle animations bring life to the entire scene. This engaging design not only delivers a clear error message but also adds charm and personality to an otherwise frustrating moment.


💻 HTML Code

1<!DOCTYPE html> 2<html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Ghost Page | 404 </title> 7 <link rel="stylesheet" href="./style.css"> 8 9 </head> 10 11 <body> 12 <div class="box"> 13 <div class="box__ghost"> 14 <div class="symbol"></div> 15 <div class="symbol"></div> 16 <div class="symbol"></div> 17 <div class="symbol"></div> 18 <div class="symbol"></div> 19 <div class="symbol"></div> 20 21 <div class="box__ghost-container"> 22 <div class="box__ghost-eyes"> 23 <div class="box__eye-left"></div> 24 <div class="box__eye-right"></div> 25 </div> 26 <div class="box__ghost-bottom"> 27 <div></div> 28 <div></div> 29 <div></div> 30 <div></div> 31 <div></div> 32 </div> 33 </div> 34 <div class="box__ghost-shadow"></div> 35 </div> 36 37 <div class="box__description"> 38 <div class="box__description-container"> 39 <div class="box__description-title">Whoops!</div> 40 <div class="box__description-text">It seems like we couldn't find the page you were looking for</div> 41 </div> 42 43 <a href="https://codepen.io/diogo_ml_gomes/" target="_blank" class="box__button">Go back</a> 44 45 </div> 46 47</div> 48 <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script><script src="./script.js"></script> 49 50 </body> 51 52</html> 53

The HTML structure defines the ghost and its surrounding elements inside a central box. It contains multiple divs for the ghost’s head, eyes, bottom curves, and decorative symbols floating around it.

A shadow element gives depth to the animation, making the ghost appear as if it’s hovering.

Below the ghost, there’s a description section displaying a friendly “Whoops!” message and a short explanation that the page couldn’t be found, along with a “Go back” button linking to an external page.

The layout is minimal yet well-organized, serving as the framework for all the visual and interactive elements handled by CSS and JavaScript.


CSS Code


1@import url(https://fonts.googleapis.com/css?family=Ubuntu); 2html, body { 3 background: #28254C; 4 font-family: "Ubuntu"; 5} 6 7* { 8 box-sizing: border-box; 9} 10 11.box { 12 width: 350px; 13 height: 100%; 14 max-height: 600px; 15 min-height: 450px; 16 background: #332F63; 17 border-radius: 20px; 18 position: absolute; 19 left: 50%; 20 top: 50%; 21 transform: translate(-50%, -50%); 22 padding: 30px 50px; 23} 24.box .box__ghost { 25 padding: 15px 25px 25px; 26 position: absolute; 27 left: 50%; 28 top: 30%; 29 transform: translate(-50%, -30%); 30} 31.box .box__ghost .symbol:nth-child(1) { 32 opacity: 0.2; 33 animation: shine 4s ease-in-out 3s infinite; 34} 35.box .box__ghost .symbol:nth-child(1):before, .box .box__ghost .symbol:nth-child(1):after { 36 content: ""; 37 width: 12px; 38 height: 4px; 39 background: #fff; 40 position: absolute; 41 border-radius: 5px; 42 bottom: 65px; 43 left: 0; 44} 45.box .box__ghost .symbol:nth-child(1):before { 46 transform: rotate(45deg); 47} 48.box .box__ghost .symbol:nth-child(1):after { 49 transform: rotate(-45deg); 50} 51.box .box__ghost .symbol:nth-child(2) { 52 position: absolute; 53 left: -5px; 54 top: 30px; 55 height: 18px; 56 width: 18px; 57 border: 4px solid; 58 border-radius: 50%; 59 border-color: #fff; 60 opacity: 0.2; 61 animation: shine 4s ease-in-out 1.3s infinite; 62} 63.box .box__ghost .symbol:nth-child(3) { 64 opacity: 0.2; 65 animation: shine 3s ease-in-out 0.5s infinite; 66} 67.box .box__ghost .symbol:nth-child(3):before, .box .box__ghost .symbol:nth-child(3):after { 68 content: ""; 69 width: 12px; 70 height: 4px; 71 background: #fff; 72 position: absolute; 73 border-radius: 5px; 74 top: 5px; 75 left: 40px; 76} 77.box .box__ghost .symbol:nth-child(3):before { 78 transform: rotate(90deg); 79} 80.box .box__ghost .symbol:nth-child(3):after { 81 transform: rotate(180deg); 82} 83.box .box__ghost .symbol:nth-child(4) { 84 opacity: 0.2; 85 animation: shine 6s ease-in-out 1.6s infinite; 86} 87.box .box__ghost .symbol:nth-child(4):before, .box .box__ghost .symbol:nth-child(4):after { 88 content: ""; 89 width: 15px; 90 height: 4px; 91 background: #fff; 92 position: absolute; 93 border-radius: 5px; 94 top: 10px; 95 right: 30px; 96} 97.box .box__ghost .symbol:nth-child(4):before { 98 transform: rotate(45deg); 99} 100.box .box__ghost .symbol:nth-child(4):after { 101 transform: rotate(-45deg); 102} 103.box .box__ghost .symbol:nth-child(5) { 104 position: absolute; 105 right: 5px; 106 top: 40px; 107 height: 12px; 108 width: 12px; 109 border: 3px solid; 110 border-radius: 50%; 111 border-color: #fff; 112 opacity: 0.2; 113 animation: shine 1.7s ease-in-out 7s infinite; 114} 115.box .box__ghost .symbol:nth-child(6) { 116 opacity: 0.2; 117 animation: shine 2s ease-in-out 6s infinite; 118} 119.box .box__ghost .symbol:nth-child(6):before, .box .box__ghost .symbol:nth-child(6):after { 120 content: ""; 121 width: 15px; 122 height: 4px; 123 background: #fff; 124 position: absolute; 125 border-radius: 5px; 126 bottom: 65px; 127 right: -5px; 128} 129.box .box__ghost .symbol:nth-child(6):before { 130 transform: rotate(90deg); 131} 132.box .box__ghost .symbol:nth-child(6):after { 133 transform: rotate(180deg); 134} 135.box .box__ghost .box__ghost-container { 136 background: #fff; 137 width: 100px; 138 height: 100px; 139 border-radius: 100px 100px 0 0; 140 position: relative; 141 margin: 0 auto; 142 animation: upndown 3s ease-in-out infinite; 143} 144.box .box__ghost .box__ghost-container .box__ghost-eyes { 145 position: absolute; 146 left: 50%; 147 top: 45%; 148 height: 12px; 149 width: 70px; 150} 151.box .box__ghost .box__ghost-container .box__ghost-eyes .box__eye-left { 152 width: 12px; 153 height: 12px; 154 background: #332F63; 155 border-radius: 50%; 156 margin: 0 10px; 157 position: absolute; 158 left: 0; 159} 160.box .box__ghost .box__ghost-container .box__ghost-eyes .box__eye-right { 161 width: 12px; 162 height: 12px; 163 background: #332F63; 164 border-radius: 50%; 165 margin: 0 10px; 166 position: absolute; 167 right: 0; 168} 169.box .box__ghost .box__ghost-container .box__ghost-bottom { 170 display: flex; 171 position: absolute; 172 top: 100%; 173 left: 0; 174 right: 0; 175} 176.box .box__ghost .box__ghost-container .box__ghost-bottom div { 177 flex-grow: 1; 178 position: relative; 179 top: -10px; 180 height: 20px; 181 border-radius: 100%; 182 background-color: #fff; 183} 184.box .box__ghost .box__ghost-container .box__ghost-bottom div:nth-child(2n) { 185 top: -12px; 186 margin: 0 0px; 187 border-top: 15px solid #332F63; 188 background: transparent; 189} 190.box .box__ghost .box__ghost-shadow { 191 height: 20px; 192 box-shadow: 0 50px 15px 5px #3B3769; 193 border-radius: 50%; 194 margin: 0 auto; 195 animation: smallnbig 3s ease-in-out infinite; 196} 197.box .box__description { 198 position: absolute; 199 bottom: 30px; 200 left: 50%; 201 transform: translateX(-50%); 202} 203.box .box__description .box__description-container { 204 color: #fff; 205 text-align: center; 206 width: 200px; 207 font-size: 16px; 208 margin: 0 auto; 209} 210.box .box__description .box__description-container .box__description-title { 211 font-size: 24px; 212 letter-spacing: 0.5px; 213} 214.box .box__description .box__description-container .box__description-text { 215 color: #8C8AA7; 216 line-height: 20px; 217 margin-top: 20px; 218} 219.box .box__description .box__button { 220 display: block; 221 position: relative; 222 background: #FF5E65; 223 border: 1px solid transparent; 224 border-radius: 50px; 225 height: 50px; 226 text-align: center; 227 text-decoration: none; 228 color: #fff; 229 line-height: 50px; 230 font-size: 18px; 231 padding: 0 70px; 232 white-space: nowrap; 233 margin-top: 25px; 234 transition: background 0.5s ease; 235 overflow: hidden; 236 -webkit-mask-image: -webkit-radial-gradient(white, black); 237} 238.box .box__description .box__button:before { 239 content: ""; 240 position: absolute; 241 width: 20px; 242 height: 100px; 243 background: #fff; 244 bottom: -25px; 245 left: 0; 246 border: 2px solid #fff; 247 transform: translateX(-50px) rotate(45deg); 248 transition: transform 0.5s ease; 249} 250.box .box__description .box__button:hover { 251 background: transparent; 252 border-color: #fff; 253} 254.box .box__description .box__button:hover:before { 255 transform: translateX(250px) rotate(45deg); 256} 257 258@keyframes upndown { 259 0% { 260 transform: translateY(5px); 261 } 262 50% { 263 transform: translateY(15px); 264 } 265 100% { 266 transform: translateY(5px); 267 } 268} 269@keyframes smallnbig { 270 0% { 271 width: 90px; 272 } 273 50% { 274 width: 100px; 275 } 276 100% { 277 width: 90px; 278 } 279} 280@keyframes shine { 281 0% { 282 opacity: 0.2; 283 } 284 25% { 285 opacity: 0.1; 286 } 287 50% { 288 opacity: 0.2; 289 } 290 100% { 291 opacity: 0.2; 292 } 293} 294

The CSS defines the spooky yet cute visual theme of the page. It uses a dark purple background with a contrasting light-colored ghost created entirely from div elements. Animations such as upndown make the ghost float up and down continuously, while smallnbig changes the width of the shadow to simulate hovering. The glowing symbols around the ghost pulse with an infinite “shine” animation, giving the illusion of flickering lights in a dark room. The ghost’s eyes, circular body, and bumpy bottom edges are all styled and aligned precisely to achieve a cartoon-like look. The “Go back” button features a soft gradient animation that slides when hovered, maintaining the playful tone. Overall, CSS is responsible for all shapes, colors, and smooth motion that define the ghost’s personality.


Javascipt Code


1//based on https://dribbble.com/shots/3913847-404-page 2 3var pageX = $(document).width(); 4var pageY = $(document).height(); 5var mouseY=0; 6var mouseX=0; 7 8$(document).mousemove(function( event ) { 9 //verticalAxis 10 mouseY = event.pageY; 11 yAxis = (pageY/2-mouseY)/pageY*300; 12 //horizontalAxis 13 mouseX = event.pageX / -pageX; 14 xAxis = -mouseX * 100 - 100; 15 16 $('.box__ghost-eyes').css({ 'transform': 'translate('+ xAxis +'%,-'+ yAxis +'%)' }); 17 18 //console.log('X: ' + xAxis); 19 20}); 21

The JavaScript script adds interactivity to the design, using jQuery to track the user’s mouse movement. It calculates the mouse’s position on the page and dynamically adjusts the translation of the ghost’s eyes using CSS transforms. As the cursor moves, the eyes appear to follow it, giving the ghost a sense of awareness and engagement. The vertical and horizontal positions are calculated relative to the window’s width and height, creating a realistic tracking effect. This simple yet clever interactivity enhances the user experience, making the ghost feel alive and responsive.

Love this component?

Explore more components and build amazing UIs.

View All Components