webdevpuneet.com

3D Pin Card — Tilt, Glare & Floating Pin Hover HTML CSS JS

3D Pin Card · Cards · Plain HTML, CSS & JS · Live preview

CategoryCards

Copy & paste

Source Code

<div class="pc-stage">
  <article class="pc-pin" id="pcPin" tabindex="0" aria-label="Featured project: Aurora Design System">
    <div class="pc-card">
      <div class="pc-thumb" aria-hidden="true">
        <div class="pc-win">
          <div class="pc-win-bar"><i></i><i></i><i></i></div>
          <div class="pc-win-body"><b></b><b></b><b></b></div>
        </div>
      </div>
      <div class="pc-body">
        <span class="pc-badge"><span class="pc-badge-dot"></span>Featured project</span>
        <h3>Aurora Design System</h3>
        <p>A themeable UI kit with 60+ accessible components, shipped as plain HTML, CSS and JavaScript.</p>
        <ul class="pc-tags"><li>HTML</li><li>CSS 3D</li><li>A11y</li></ul>
        <div class="pc-foot">
          <a class="pc-visit" href="https://webdevpuneet.com/ui-snippets/" target="_blank" rel="noopener">Visit site <span aria-hidden="true">→</span></a>
          <button class="pc-copy" id="pcCopy" type="button"><span id="pcCopyTxt" aria-live="polite">Copy link</span></button>
        </div>
      </div>
      <span class="pc-glare" aria-hidden="true"></span>
    </div>

    <div class="pc-anchor" aria-hidden="true">
      <span class="pc-label"><i class="pc-fav"></i>webdevpuneet.com/ui-snippets</span>
      <span class="pc-beam"></span>
      <span class="pc-core"></span>
      <span class="pc-ring"></span>
      <span class="pc-ring pc-ring2"></span>
    </div>
  </article>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Real 3D perspective
A perspective stage plus preserve-3d gives the card and pin true depth.
Bottom-anchored tilt
transform-origin at the bottom edge makes the top recede while the pin stays planted.
Eased cursor tracking
pointermove sets a target and a rAF loop glides toward it, then stops itself when settled.
Cursor glare highlight
A radial gradient follows the pointer via --gx / --gy for a glass-like sheen.
Rising pin
A URL label, gradient beam, glowing core and two staggered ripple rings animate in with pure CSS.
Keyboard and touch ready
The effect runs on :hover and :focus-within, with visible focus rings on every control.
Robust copy button
Clipboard API with a textarea fallback and an aria-live result message.
Reduced-motion friendly
prefers-reduced-motion removes animation and applies the tilt instantly.

About this UI Snippet

3D Pin Card — Cursor Tilt, Glare Highlight & a Rising Anchor Pin

Screenshot of the 3D Pin Card snippet rendered live

The 3D pin card is a hover interaction popularised by modern component libraries: a card tilts back into the scene while a "pin" — a floating label, a glowing beam and rippling rings — rises beneath it, as if the card were staked to a point in space. This version is a complete project card with a preview thumbnail, status badge, tags, a visit link and a copy-link button, built with plain HTML, CSS 3D transforms and a small vanilla JavaScript tilt loop.

Establishing 3D space

Everything sits in a perspective: 1100px stage, which gives child transforms real depth — without it, rotateX just looks like a flat squash. The pin wrapper uses transform-style: preserve-3d so the card and the pin keep their own positions in 3D instead of flattening into one plane.

The backward tilt, anchored at the bottom

On hover or keyboard focus the card rotates with rotateX(24deg) scale(.96) around transform-origin: 50% 100%. Anchoring the rotation at the bottom edge means the top recedes while the bottom stays planted exactly where the pin sits, which is what sells the illusion. A soft indigo shadow grows underneath, and the pin is lifted forward with translateZ(90px) so the card's shadow, which lives in the tilted plane, can never cover it. The thumbnail's mini browser window slides up slightly for extra depth.

The pin: label, beam, core and rings

Four small elements rise from beneath the card: a pill-shaped label with the destination URL, a .pc-beam that grows downward with a gradient fade, a glowing .pc-core dot at its tip, and two .pc-ring circles rotated 72° into the floor plane that pcPing outward and fade on a staggered loop, like ripples around the pin's base. All of it is pure CSS and driven by :hover and :focus-within, so keyboard and touch users get the same effect.

Smooth cursor-tracking tilt and glare

A pointermove handler converts the cursor position to a -0.5…0.5 range and only sets a target. A requestAnimationFrame loop eases the current rotation toward that target (14% per frame) and writes it to --rx and --ry custom properties, so the card glides instead of snapping, and the loop stops itself once it settles. The same handler updates --gx and --gy, which position a radial-gradient glare over the card so a highlight slides under the pointer like light on glass.

Copy link with a safe fallback

The copy button uses the async Clipboard API when available and falls back to a hidden textarea with document.execCommand('copy'), so it still works in iframes and older browsers. The button text lives in an aria-live region and switches to "Copied ✓" or "Copy failed", so the result is announced to screen readers. The card itself stays a normal article with a real link, so clicking never hijacks navigation.

Accessibility and motion

The card is focusable (tabindex="0"), shows the pin on :focus-within, and the buttons have visible focus rings. With prefers-reduced-motion, animations and easing are switched off and the tilt applies instantly.

Customizing it

Change the rotateX(24deg) for a steeper or gentler tilt, the 14 and 10 multipliers for how strongly it follows the cursor, and the beam height and ring size for a taller pin. Recolour the indigo accent, swap the thumbnail for a real screenshot, and set the label and LINK to your URL. For other pointer-reactive cards, see the glare card and spotlight card; for grids of cards try focus cards or a meteor card.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA project card renders flat with a thumbnail, badge, tags and two actions. The pin is hidden underneath it.
  2. 2
    Hover or focus the cardIt tilts back in 3D while a URL label, a beam, a glowing core and ripple rings rise beneath it. Tab onto it to get the same effect from the keyboard.
  3. 3
    Move the cursorThe whole assembly eases toward the pointer and a glare highlight slides across the card surface.
  4. 4
    Click Copy linkThe link is copied (with a fallback for older browsers) and the button confirms with "Copied ✓".
  5. 5
    Click Visit siteIt's a real anchor, so it navigates normally. Set the href to your project URL.
  6. 6
    Make it yoursEdit the title, text, tags and label, set the LINK constant in the JS, and replace the thumbnail with your own screenshot.

Real-world uses

Common Use Cases

Featured project cards
Spotlight a case study or open-source project inside a focus cards grid, with the pin showing the destination URL on hover.
Portfolio highlights
Pin your best project in a portfolio hero so visitors see the live link rising from the card.
Product and tool directories
Give each listing a thumbnail, tags and a copy-link action, and pair with a meteor card for variety.
Profile card upgrades
Turn a flat profile card into a 3D one where the pin shows a handle or website.
Link-in-bio pages
Make a shareable link the centrepiece, with Copy link for quick sharing and a real Visit anchor for navigation.

Got questions?

Frequently Asked Questions

perspective: 1100px on the stage gives 3D transforms real depth. Without it, rotateX looks like a vertical squash. The pin wrapper also uses transform-style: preserve-3d so the card and pin keep their own 3D positions instead of flattening into one plane.

The card uses transform-origin: 50% 100%, so rotateX moves the top edge back while the bottom stays where the pin attaches. With the default centre origin the bottom would swing forward and detach from the beam.

pointermove only stores a target rotation. A requestAnimationFrame loop moves the current rotation 14% of the way there each frame and writes --rx and --ry on the wrapper. It cancels itself when the difference is tiny, so it costs nothing while idle.

The pin shows on :focus-within, and the card has tabindex="0", so tapping it focuses it and raises the pin. For a persistent state on touch, add a class on tap and include it in the same selectors as :hover and :focus-within.

Render the markup as a component and keep the CSS. Hold the target rotation in a ref, run the rAF loop in an effect, and write --rx, --ry, --gx and --gy through the element's style. The pin animation is pure CSS and needs no JS. In Tailwind, use arbitrary values for perspective, rotate-x and the beam height.