Skip to content

Tilt Card

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

Cards & HoverHTMLCSSJavaScriptany framework
Tilt Card
Hover to tilt

Copy into your project

HTML
<!-- Tilt Card — card that tilts toward cursor on hover -->
<div class="nuda-tilt-card">
  <div class="nuda-tilt-card__content">
    <div class="nuda-tilt-card__icon">&#9830;</div>
    <h3 class="nuda-tilt-card__title">Tilt Card</h3>
    <p class="nuda-tilt-card__desc">Hover to see the 3D tilt effect</p>
  </div>
</div>
CSS
/* ── Tilt Card ───────────────────────────────────────────────
   The tilt is JS-driven via CSS custom properties.
   Customize:
     --nuda-tc-bg      : card background
     --nuda-tc-clr     : text color
     --nuda-tc-radius  : corner radius
     --nuda-tc-shadow  : box shadow
   ──────────────────────────────────────────────────────────── */
.nuda-tilt-card {
  --nuda-tc-bg: linear-gradient(135deg, #1e1b4b, #312e81);
  --nuda-tc-clr: #e0e7ff;
  --nuda-tc-radius: 16px;
  --nuda-tc-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  --nuda-tc-rx: 0deg;
  --nuda-tc-ry: 0deg;

  width: 280px;
  perspective: 800px;
}

.nuda-tilt-card__content {
  padding: 32px 24px;
  background: var(--nuda-tc-bg);
  border-radius: var(--nuda-tc-radius);
  color: var(--nuda-tc-clr);
  text-align: center;
  box-shadow: var(--nuda-tc-shadow);
  transform: rotateX(var(--nuda-tc-rx)) rotateY(var(--nuda-tc-ry));
  transition: transform 0.15s ease;
  will-change: transform;
}

.nuda-tilt-card__icon {
  font-size: 2rem;
  margin-bottom: 8px;
}

.nuda-tilt-card__title {
  font-size: 1.1rem;
  font-weight: 700;
  margin: 0;
}

.nuda-tilt-card__desc {
  font-size: 0.85rem;
  opacity: 0.7;
  margin: 6px 0 0;
}

/* ── Accessibility ──────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .nuda-tilt-card__content {
    transition: none;
    transform: none !important;
  }
}
JavaScript
/* ── Tilt Card — vanilla JS ──────────────────────────────────
   Applies 3D tilt via CSS custom properties based on cursor
   position. Respects prefers-reduced-motion.
   ──────────────────────────────────────────────────────────── */
;(function () {
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;

  var maxTilt = 15; /* degrees */

  document.querySelectorAll(".nuda-tilt-card").forEach(function (card) {
    var content = card.querySelector(".nuda-tilt-card__content");
    if (!content) return;

    card.addEventListener("mousemove", function (e) {
      var rect = card.getBoundingClientRect();
      var x = (e.clientX - rect.left) / rect.width;   /* 0 → 1 */
      var y = (e.clientY - rect.top) / rect.height;    /* 0 → 1 */

      var rotateX = (0.5 - y) * maxTilt;  /* tilt up/down */
      var rotateY = (x - 0.5) * maxTilt;  /* tilt left/right */

      content.style.setProperty("--nuda-tc-rx", rotateX + "deg");
      content.style.setProperty("--nuda-tc-ry", rotateY + "deg");
    });

    card.addEventListener("mouseleave", function () {
      content.style.setProperty("--nuda-tc-rx", "0deg");
      content.style.setProperty("--nuda-tc-ry", "0deg");
    });
  });
})();

How to use Tilt Card

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 cards & hover components

← Browse all NudaUI components