DEMO
CODE
<div class="demo-stage c3p-stage">
<a class="c3p-scene" href="#" onclick="return false;" aria-label="3D Pin Card デモ">
<span class="c3p-label">/ui/motion-lab</span>
<span class="c3p-line" aria-hidden="true"></span>
<span class="c3p-ring" aria-hidden="true"></span>
<span class="c3p-card">
<span class="c3p-title">MOTION LAB</span>
<span class="c3p-text">動くデモ・コピー可能なコード・AIプロンプトの3点セット。</span>
</span>
</a>
</div>
.c3p-stage { display:flex; align-items:center; justify-content:center; padding:3rem 1.5rem; background:#0B0B10; min-height:300px; perspective:1000px; }
.c3p-scene {
position:relative; display:block; width:230px; height:150px;
transform-style:preserve-3d; text-decoration:none;
transition: transform .6s cubic-bezier(.23,1,.32,1);
}
.c3p-scene:hover, .c3p-scene:focus-visible { transform: rotateX(38deg) scale(.92); }
.c3p-scene:focus-visible { outline:2px solid #E91B89; outline-offset:8px; }
.c3p-card {
position:absolute; inset:0; display:flex; flex-direction:column; gap:.6rem;
padding:1.2rem 1.3rem; border-radius:14px;
background:linear-gradient(160deg,#1A1A22 0%,#101017 100%);
border:1px solid rgba(255,255,255,.1);
box-shadow:0 18px 40px rgba(0,0,0,.45);
}
.c3p-title { font-family:'Oswald',sans-serif; font-size:.95rem; letter-spacing:.2em; color:#fff; }
.c3p-text { font-size:.76rem; line-height:1.7; color:#9A9AA5; }
.c3p-label {
position:absolute; top:-2.6rem; left:50%; z-index:2;
transform:translate(-50%, 10px) translateZ(0); opacity:0;
padding:.32rem .9rem; border-radius:999px;
background:#E91B89; color:#fff;
font-family:'JetBrains Mono',monospace; font-size:.66rem; letter-spacing:.05em; white-space:nowrap;
transition: opacity .45s ease, transform .6s cubic-bezier(.23,1,.32,1);
}
.c3p-line {
position:absolute; top:-2.1rem; left:50%; z-index:1;
width:1px; height:0; transform:translateX(-50%);
background:linear-gradient(180deg,#E91B89,transparent);
transition: height .6s cubic-bezier(.23,1,.32,1);
}
.c3p-ring {
position:absolute; top:50%; left:50%; width:150px; height:150px; margin:-75px 0 0 -75px;
border:1px solid rgba(233,27,137,.35); border-radius:50%;
transform:translateZ(-1px) scale(.6); opacity:0;
transition: transform .6s cubic-bezier(.23,1,.32,1), opacity .45s ease;
}
.c3p-scene:hover .c3p-label, .c3p-scene:focus-visible .c3p-label { opacity:1; transform:translate(-50%,0) translateZ(60px); }
.c3p-scene:hover .c3p-line, .c3p-scene:focus-visible .c3p-line { height:2.1rem; }
.c3p-scene:hover .c3p-ring, .c3p-scene:focus-visible .c3p-ring { opacity:1; transform:translateZ(-1px) scale(1.15); }
@media (prefers-reduced-motion: reduce) {
.c3p-scene, .c3p-label, .c3p-line, .c3p-ring { transition-duration:.01ms; }
}
AI PROMPT
ホバーするとカードが奥へ倒れ、留めピンとラベルが手前に立ち上がる3Dピンカードを作って。親(ステージ)に perspective: 1000px、カードのラッパーに transform-style: preserve-3d を指定するのが前提。ホバー時はラッパーに transform: rotateX(38deg) scale(.92) を掛けて奥へ倒す。ラベルは絶対配置でカード上部に置き、通常時は opacity: 0 と translateY のオフセット、ホバー時に opacity: 1 と translateZ(60px) で手前へ引き出す(preserve-3d があるので translateZ が実際の奥行きとして効く)。ピンの支柱は幅1pxの要素の height を 0 から 2.1rem へトランジションさせると、下から伸びる線に見える。カード背面に translateZ(-1px) の円リングを置き、ホバーで scale を上げると設置面の広がりが出る。イージングは cubic-bezier(.23,1,.32,1)、duration は 0.6s 前後。a 要素で組み、:hover と :focus-visible の両方に同じ指定を書くこと(キーボード操作でも同じ体験になる)。 Acceptance criteria: works with prefers-reduced-motion (animation disabled), zero console errors, zero layout shift
AIエージェントでの実装ガイド → Claude Code でWebアニメーションを実装する
BOOKS · PR · AMAZON
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
学びを止めない · AMAZONサブスク
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
ホバーするとカードが奥へ倒れ込み、地図のピンのようなラベルが手前に立ち上がる演出です。Aceternity UI の 3D Pin として広まりました。perspective と preserve-3d による本物の3D空間の中で、要素ごとに translateZ の値を変えて階層を作るのが構造の核です。
当サイトの Tilt 3D Hover はカーソル位置に応じてカードが傾く表現で、傾きの向きがマウスに追従します。本ページは傾きが固定で、代わりに「ピンが立ち上がる」という別レイヤーの動きが主役という別テーマです。ポートフォリオのリンクカードや、地図・場所に紐づくコンテンツと相性が良くなります。
translateZ が効かない場合は、ほぼ確実に preserve-3d か perspective の指定漏れです。この2つはセットで確認してください。
translateZ が効かないのはなぜですか?
祖先に transform-style: preserve-3d が指定されていないためです。既定の flat では子要素が親の平面に押し潰され、translateZ が無視されます。さらに perspective は3D空間を見る側(親)に指定する必要があり、これが欠けても奥行きは出ません。preserve-3d と perspective はセットで確認してください。
カードが倒れると文字がぼやけます。
3D変形中はサブピクセルのラスタライズが変わるため、環境によって文字が滲むことがあります。rotateX の角度を控えめ(30〜40度程度)にする、変形対象を画像やカード面に限定して細かい文字を持たせない、といった調整で目立たなくなります。will-change: transform を付けるとレイヤー昇格が安定します。
コードは無料で使えますか?
はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。