-
CSS text spotlight animation
HTML
CSS
JavaScript
SPOTLIGHT
:root { --bg-color: #0f0f13; --base-text: #22252a; /* Dim background text */ --reveal-text: #fff; /* Bright spotlighted text */ --spotlight-size: 120px; /* These variables will be updated by JavaScript */ --mouse-x: -500px; --mouse-y: -500px; } body { margin: 0; background-color: var(--bg-color); display: flex; justify-content: center; align-items: center; min-height: 100vh; font-family: 'Arial Black', Impact, sans-serif; overflow: hidden; } /* The interactive container */ .spotlight-container { position: relative; padding: 40px; cursor: none; /* Hides the default mouse cursor for a cleaner look */ } /* Base Layer (Dark) */ .spotlight-text { font-size: 8vw; color: var(--base-text); letter-spacing: 6px; margin: 0; text-transform: uppercase; position: relative; user-select: none; } /* Hover Layer (Bright) */ .spotlight-text::after { content: 'SPOTLIGHT'; position: absolute; top: 0; left: 0; width: 100%; height: 100%; color: var(--reveal-text); -webkit-mask-image: radial-gradient( circle var(--spotlight-size) at var(--mouse-x) var(--mouse-y), rgba(0,0,0,1) 30%, rgba(0,0,0,0) 100__% ); mask-image: radial-gradient( circle var(--spotlight-size) at var(--mouse-x) var(--mouse-y), rgba(0,0,0,1) 30%, rgba(0,0,0,0) 100% ); }
const container = document.querySelector('.spotlight-container'); const text = document.querySelector('.spotlight-text'); container.addEventListener('mousemove', (e) => { // Get boundaries of the text element to calculate coordinates accurately const rect = text.getBoundingClientRect(); /* Calculate mouse coordinates relative to the top-left of the text */ const x = e.clientX - rect.left; const y = e.clientY - rect.top; // Update the CSS variables in real-time text.style.setProperty('--mouse-x', `${x}px`); text.style.setProperty('--mouse-y', `${y}px`); }); /* Optional: Hide the spotlight when the mouse leaves the container */ container.addEventListener('mouseleave', () => { text.style.setProperty('--mouse-x', '-500px'); text.style.setProperty('--mouse-y', '-500px'); });
Live Preview