respond

Tags that make surfaces answer your pointer like objects on a table. Move over them, pull them around, press them. On a phone, the keypad under press is the one made for your thumb.

hover

grow
turn
lean
slide

<motion-hover> move over each shape: scale, rotate, skew and slide, then it springs back

Show the codeHide the code
<script type="module">
  import "motion-components/motion-hover";
</script>

<div class="table">
  <motion-hover scale="1.18" bounce="0.5">
    <div class="disc">grow</div>
  </motion-hover>
  <motion-hover scale="1.06" rotate="-12" bounce="0.55">
    <div class="tile">turn</div>
  </motion-hover>
  <motion-hover scale="1" skew="-10" y="-18" bounce="0.45">
    <div class="slab">lean</div>
  </motion-hover>
  <motion-hover scale="1.04" x="28" bounce="0.6">
    <div class="pill">slide</div>
  </motion-hover>
</div>

<style>
  .table { display: flex; flex-wrap: wrap; align-items: center; gap: 3rem; }
  .table div { display: grid; place-items: center; font-weight: 700; user-select: none; }
  .disc { width: 10rem; aspect-ratio: 1; border-radius: 50%; background: var(--mc-color-yellow, #facc15); color: #0f0f13; }
  .tile { width: 9rem; aspect-ratio: 1; border-radius: 1.25rem; background: var(--mc-color-accent, #2563eb); color: #fff; }
  .slab { width: 6rem; height: 13rem; border-radius: 0.5rem; background: var(--mc-color-surface-2, #f0f0f8); border: 1px solid var(--mc-color-border, #dddde8); }
  .pill { width: 12rem; height: 4.5rem; border-radius: 999px; border: 2px solid var(--mc-color-yellow, #facc15); color: var(--mc-color-yellow, #a16207); }
</style>

magnetic

0.25
0.5
0.9

<motion-magnetic> drag your pointer across each dot; the number is its strength

Show the codeHide the code
<script type="module">
  import "motion-components/motion-magnetic";
</script>

<div class="table">
  <motion-magnetic strength="0.25">
    <div class="dot small">0.25</div>
  </motion-magnetic>
  <motion-magnetic strength="0.5" bounce="0.5">
    <div class="dot medium">0.5</div>
  </motion-magnetic>
  <motion-magnetic strength="0.9" bounce="0.6" duration="0.8">
    <div class="dot large">0.9</div>
  </motion-magnetic>
</div>

<style>
  .table { display: flex; flex-wrap: wrap; align-items: center; gap: 3rem; }
  .table motion-magnetic { padding: 2rem; }
  .dot { display: grid; place-items: center; aspect-ratio: 1; border-radius: 50%; font-weight: 700; user-select: none; }
  .small { width: 5.5rem; background: var(--mc-color-surface-2, #f0f0f8); border: 1px solid var(--mc-color-border, #dddde8); }
  .medium { width: 8rem; background: var(--mc-color-accent, #2563eb); color: #fff; }
  .large { width: 11rem; background: var(--mc-color-yellow, #facc15); color: #0f0f13; font-size: 2rem; }
</style>

press

0 presses

<motion-press> press and hold a key; deeper keys squash further and bounce back harder

Show the codeHide the code
<script type="module">
  import "motion-components/motion-press";
</script>

<p aria-live="polite"><span data-count>0</span> presses</p>
<div class="keys">
  <motion-press scale="0.94">
    <button type="button" class="key" data-add="1">+1</button>
  </motion-press>
  <motion-press scale="0.86" bounce="0.6">
    <button type="button" class="key big" data-add="10">+10</button>
  </motion-press>
  <motion-press scale="0.9">
    <button type="button" class="key quiet" data-reset>reset</button>
  </motion-press>
</div>

<style>
  .keys { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; }
  .key {
    width: 8rem; aspect-ratio: 1; border: 0; border-radius: 1.5rem; cursor: pointer;
    background: var(--mc-color-accent, #2563eb); color: #fff; font-size: 2rem; font-weight: 800;
    box-shadow: 0 6px 0 #1e40af; touch-action: manipulation;
  }
  .key.big { width: 10.5rem; background: var(--mc-color-yellow, #facc15); color: #0f0f13; box-shadow: 0 6px 0 #a16207; }
  .key.quiet { background: var(--mc-color-surface-2, #f0f0f8); color: inherit; font-size: 1.25rem; box-shadow: 0 6px 0 #dddde8; }
</style>

<script>
  const out = document.querySelector("[data-count]");
  let count = 0;
  document.querySelectorAll(".key").forEach((key) =>
    key.addEventListener("click", () => {
      count = key.hasAttribute("data-reset") ? 0 : count + Number(key.dataset.add);
      out.textContent = String(count);
    }),
  );
</script>

tilt

25°with gloss
10°no gloss
6°a wide poster, barely tilting

<motion-tilt> move across each card; the number is how far it can turn

Show the codeHide the code
<script type="module">
  import "motion-components/motion-tilt";
</script>

<div class="table">
  <motion-tilt max="25" gloss>
    <div class="card yellow"><strong>25°</strong><span>with gloss</span></div>
  </motion-tilt>
  <motion-tilt max="10" scale="1.02">
    <div class="card blue"><strong>10°</strong><span>no gloss</span></div>
  </motion-tilt>
  <motion-tilt max="6" scale="1.03" gloss>
    <div class="card wide"><strong>6°</strong><span>a wide poster, barely tilting</span></div>
  </motion-tilt>
</div>

<style>
  .table { display: flex; flex-wrap: wrap; align-items: stretch; gap: 3rem; }
  .card {
    box-sizing: border-box; display: grid; align-content: space-between; gap: 1rem;
    padding: 1.25rem; border-radius: 1rem; font-weight: 600; user-select: none;
  }
  .card strong { font-size: 3.5rem; line-height: 1; }
  .yellow { width: 12rem; aspect-ratio: 5 / 7; background: var(--mc-color-yellow, #facc15); color: #0f0f13; }
  .blue { width: 12rem; aspect-ratio: 5 / 7; background: var(--mc-color-accent, #2563eb); color: #fff; }
  .wide { width: 24rem; height: 100%; min-height: 12rem; background: var(--mc-color-surface-2, #f0f0f8); border: 1px solid var(--mc-color-border, #dddde8); }
</style>