Skip to content

Perspective Tilt

A copy-paste 3d effects component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.

3D EffectsHTMLCSSJavaScriptany framework
Hover to tilt

Copy into your project

HTML
<div class="nuda-tilt" style="perspective: 600px">
  <div class="nuda-tilt__card">
    <p>Hover to tilt in 3D</p>
  </div>
</div>
CSS
/* Perspective Tilt
   Element that tilts toward the cursor in 3D on hover.
   Customize: --tilt-max (degrees), --tilt-speed */

.nuda-tilt {
  perspective: 600px;
  display: inline-block;
}

.nuda-tilt__card {
  --tilt-max: 15deg;
  --tilt-speed: 0.15s;
  width: 200px;
  height: 140px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ccc;
  font-size: 0.85rem;
  transition: transform var(--tilt-speed) ease, box-shadow var(--tilt-speed) ease;
  cursor: pointer;
  will-change: transform;
}

.nuda-tilt__card:hover {
  box-shadow: 0 10px 40px rgba(228, 255, 84, 0.08);
}

@media (prefers-reduced-motion: reduce) {
  .nuda-tilt__card {
    transition: none;
  }
}
JavaScript
/* Perspective Tilt — Tilts the card toward the cursor position. */

(function () {
  var cards = document.querySelectorAll('.nuda-tilt__card');
  if (!cards.length) return;

  var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (reducedMotion) return;

  var maxDeg = 15;

  cards.forEach(function (card) {
    card.addEventListener('mousemove', function (e) {
      var rect = card.getBoundingClientRect();
      var x = (e.clientX - rect.left) / rect.width;   // 0 to 1
      var y = (e.clientY - rect.top) / rect.height;    // 0 to 1
      var rotateX = (0.5 - y) * maxDeg * 2;            // tilt up/down
      var rotateY = (x - 0.5) * maxDeg * 2;            // tilt left/right
      card.style.transform =
        'rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
    });

    card.addEventListener('mouseleave', function () {
      card.style.transform = 'rotateX(0deg) rotateY(0deg)';
    });
  });
})();

How to use Perspective Tilt

Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.

Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.

More 3d effects components

← Browse all NudaUI components