Advertisement

GSAP Magic Hover Areas

| by Vladimir | 3 min read | code by Ryan Yu
A11y Ready Intermediate

Tech & Dependencies

HTML SCSS JavaScript
GSAP Lodash.js VanillaTilt.js

Features

  • Floating Background
  • GSAP Animation
  • Focus Tracking
  • Dynamic Resize

Browser Support

Chrome 49+ Safari 10+ Firefox 52+ Edge 79+

Core

This is a GSAP Magic Hover Areas component. It creates an animated, floating background layer that physically tracks the user’s cursor or keyboard focus across different interactive elements on the page. It adds a cohesive, fluid spatial awareness to standard list items and navigation menus.

Specs

  • Weight: ~80 KB (Requires GSAP core, Lodash throttle, and optionally VanillaTilt for the author card).
  • Performance: High. The script uses GSAP to animate top, left, width, and height properties. Resizing is optimized using Lodash’s _.throttle to prevent layout thrashing during window adjustments.
  • Theming / Customization: The appearance of the moving area (.c-magic-area) is controlled via SCSS variables (--gray, --black). Modifiers like --menu and --content allow different styles for different tracking areas.
  • Responsiveness: Dynamic. Listens to the window resize event to recalculate bounding boxes and instantly snap the magic area back to its correct coordinates.
  • Graceful Degradation: Perfect. If JavaScript fails or GSAP fails to load, the links and articles remain fully visible, styled, and clickable without the floating background effect.

Anatomy

The component separates the visual tracking layer from the semantic interactive elements.

  • HTML (The Skeleton): The core content uses semantic tags (nav, ul, article, a). At the top of the DOM sit standalone div elements with the .c-magic-area class. These act as invisible, absolute-positioned proxies.
  • CSS (The Skin): The .c-magic-area elements are given a z-index: -1, placing them visually beneath the links. The links themselves are styled normally but use pointer-events: none on child elements to ensure hover events fire consistently on the parent wrapper.
  • JS (The Nervous System): Scans the DOM for .c-magic-area elements, reads their data-target-class attribute to find the associated links, and attaches mouseenter, mouseleave, focus, and focusout event listeners. It dynamically retrieves the dimensions and offsets of the hovered link and uses GSAP to tween the magic area to those exact coordinates.

Logic

The system is highly reusable because it reads configuration data directly from the HTML dataset attributes rather than hardcoding targets in JS.

const getAreaDetails = (area) => {
  const width = area.clientWidth;
  const height = area.clientHeight;
  const position = area.getBoundingClientRect();
  const top = position.top + window.scrollY;
  const left = position.left;
  
  return { left, height, top, width };
};

This function is the mathematical core. getBoundingClientRect() provides the element’s position relative to the viewport. However, because the user might scroll down the page, position.top alone would cause the magic area to detach from the element. By adding window.scrollY to the calculation, the script accurately anchors the floating background relative to the document, ensuring flawless tracking regardless of scroll depth.

Feel

Fluid and attentive. As you move the mouse across the navigation bar, the grey background block stretches and slides to catch the cursor, giving the interface a snappy, magnetic elasticity. The component respects accessibility by mirroring this exact behavior for keyboard navigation via focus and focusout events. The optional data-tween-back="true" configuration on the main menu ensures that when the user stops interacting, the background physically retreats to its designated “home” position (the active page link), providing satisfying closure to the interaction.

Advertisement