About this snippet

Design a highly engaging call-to-action with an interactive magnetic cursor link. The entire button intelligently pulls towards the users mouse, creating a physical gravity effect.

Size
2.4 KB
Uses
HTML, CSS, JavaScript
Loads
Nothing external
Views
271
<div class="magnet-area" id="magnet-area">
  <a href="#" class="magnet-btn" id="magnet-btn">
    <span class="btn-text" id="btn-text">Hover Me</span>
  </a>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: #f8fafc;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

.magnet-area {
  width: 300px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  /* Helpful border just for visualizing the trigger zone */
  border: 1px dashed #cbd5e1;
  border-radius: 50%;
}

.magnet-btn {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 140px;
  height: 140px;
  background: #0f172a;
  color: #ffffff;
  border-radius: 50%;
  text-decoration: none;
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 1px;
  box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
  will-change: transform;
}

.btn-text {
  pointer-events: none;
  transition: transform 0.2s cubic-bezier(0.25, 1, 0.5, 1);
}
const area = document.getElementById("magnet-area");
const btn = document.getElementById("magnet-btn");
const text = document.getElementById("btn-text");

area.addEventListener("mousemove", function(e) {
  const rect = area.getBoundingClientRect();
  const centerX = rect.left + rect.width / 2;
  const centerY = rect.top + rect.height / 2;
  
  /* Calculate distance from center */
  const deltaX = e.clientX - centerX;
  const deltaY = e.clientY - centerY;
  
  /* Apply a fraction of the distance to the button (pulls it toward cursor) */
  btn.style.transform = "translate(" + (deltaX * 0.4) + "px, " + (deltaY * 0.4) + "px)";
  
  /* Apply an even smaller fraction to the text to create a parallax depth effect */
  text.style.transform = "translate(" + (deltaX * 0.15) + "px, " + (deltaY * 0.15) + "px)";
});

area.addEventListener("mouseleave", function() {
  /* Snap back elegantly */
  btn.style.transition = "transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)";
  text.style.transition = "transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)";
  
  btn.style.transform = "translate(0px, 0px)";
  text.style.transform = "translate(0px, 0px)";
});

area.addEventListener("mouseenter", function() {
  /* Remove transition to allow instant physics tracking */
  btn.style.transition = "none";
  text.style.transition = "none";
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save