擬似3D押し出し文字

多層 text-shadow で立体的に押し出した文字を作り、マウス追従でわずかに傾けます。レトロでインパクトのある見出しに使えます。

#css#js#3d

ライブデモ

使用例(お題: カフェ MOON BREW)

この技法を「カフェ MOON BREW」というテーマのダミーサイトで実際に使った例です。

HTML
<div class="page">
  <header class="nav">
    <div class="brand"><span class="cup"></span>MOON BREW</div>
    <span class="tag">夏季限定フェア</span>
  </header>

  <section class="hero">
    <p class="eyebrow">SUMMER COLD BREW FAIR</p>
    <h1 class="extrude">ICE<br>BREW</h1>
    <p class="lead">じっくり水出し、すっきり香る。<br>夏だけの冷たい一杯、はじまります。</p>
    <div class="row">
      <span class="chip">水出しコーヒー ¥580</span>
      <span class="chip">カフェオレ氷 ¥620</span>
    </div>
  </section>
</div>
CSS
/* MOON BREW:擬似3D押し出し見出しが主役 */
* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: "Arial Black", "Segoe UI", system-ui, sans-serif;
  background:
    radial-gradient(600px 340px at 50% -10%, #4a3320 0%, transparent 60%),
    linear-gradient(165deg, #2b1d12 0%, #1d130a 100%);
  color: #f5ede1;
  min-height: 400px;
  overflow: hidden;
  perspective: 700px;
}
.page { padding: 16px 26px; }

.nav { display: flex; align-items: center; justify-content: space-between; }
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 16px; letter-spacing: 0.06em; }
.cup { width: 16px; height: 16px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #f3d9a8, #c98a3b); }
.tag {
  font-size: 11px; color: #2b1d12; background: #c98a3b;
  padding: 4px 11px; border-radius: 14px; font-weight: 700;
}

.hero { text-align: center; padding: 22px 6px 0; }
.eyebrow {
  font-size: 11px; letter-spacing: 0.3em; color: #c98a3b; font-weight: 700;
}

/* 押し出し見出し本体:多層text-shadowで立体化、JSで傾ける */
.extrude {
  margin-top: 12px;
  font-size: clamp(46px, 11vw, 88px);
  line-height: 0.92;
  font-weight: 900;
  letter-spacing: 0.02em;
  color: #f5ede1;
  transform-style: preserve-3d;
  transition: transform 0.15s ease-out;
  text-shadow:
    1px 1px 0 #c98a3b, 2px 2px 0 #bd7f33,
    3px 3px 0 #a96f2c, 4px 4px 0 #955f25,
    5px 5px 0 #80501f, 6px 6px 0 #6b4118,
    9px 9px 18px rgba(0,0,0,0.55);
}

.lead {
  margin-top: 18px; font-size: 13.5px; line-height: 1.8; color: #cdb593;
  font-family: "Segoe UI", sans-serif;
}
.row { margin-top: 16px; display: flex; gap: 10px; justify-content: center; }
.chip {
  font-family: "Segoe UI", sans-serif;
  font-size: 12px; color: #f5ede1;
  border: 1px solid rgba(201,138,59,0.4);
  padding: 6px 13px; border-radius: 16px;
}

@media (prefers-reduced-motion: reduce) {
  .extrude { transition: none; }
}
JavaScript
// マウス追従で押し出し見出しをわずかに傾ける
(function () {
  const el = document.querySelector('.extrude');
  if (!el) return; // null安全

  const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (reduce) return; // 控えめ設定では傾けない

  function onMove(e) {
    const r = document.body.getBoundingClientRect();
    // -0.5..0.5 に正規化
    const x = (e.clientX - r.left) / r.width - 0.5;
    const y = (e.clientY - r.top) / r.height - 0.5;
    // 上下左右の傾きへ変換(控えめな角度)
    el.style.transform =
      'rotateY(' + (x * 18) + 'deg) rotateX(' + (-y * 14) + 'deg)';
  }
  function reset() { el.style.transform = ''; }

  document.body.addEventListener('mousemove', onMove);
  document.body.addEventListener('mouseleave', reset);
})();

コード

HTML
<main class="stage">
  <h1 class="extrude" data-text="RETRO">RETRO</h1>
  <p class="cap">多重 text-shadow による擬似3D押し出し</p>
</main>
CSS
* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  min-height: 360px;
  display: grid;
  place-items: center;
  background:
    radial-gradient(800px 500px at 50% 30%, #ff9e6d 0%, #ff5d8f 55%, #8b3ffd 100%);
  font-family: "Arial Black", "Segoe UI", system-ui, sans-serif;
  overflow: hidden;
  padding: 24px;
}

.stage {
  text-align: center;
  /* マウス追従でわずかに傾けるための起点 */
  perspective: 700px;
}

.extrude {
  font-size: clamp(60px, 17vw, 140px);
  font-weight: 900;
  letter-spacing: 0.04em;
  color: #fdf2e9;
  /* 影を何層も重ねて奥行きのある押し出しを表現 */
  text-shadow:
    1px 1px 0 #c2410c,
    2px 2px 0 #c2410c,
    3px 3px 0 #b03309,
    4px 4px 0 #b03309,
    5px 5px 0 #9a2c08,
    6px 6px 0 #9a2c08,
    7px 7px 0 #842506,
    8px 8px 14px rgba(0,0,0,0.4);
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .12s ease-out;
  transform-style: preserve-3d;
}

.cap {
  margin-top: 30px;
  font-family: "Segoe UI", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: rgba(255,255,255,0.85);
}
JavaScript
// マウス位置に応じて3D文字をわずかに傾ける
(function () {
  const stage = document.querySelector('.stage');
  const word = document.querySelector('.extrude');
  if (!stage || !word) return; // null安全

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

  const MAX = 14; // 最大傾き角(度)

  // ポインタの相対位置を-1..1に正規化して回転量に変換
  function onMove(e) {
    const r = stage.getBoundingClientRect();
    const x = (e.clientX - r.left) / r.width - 0.5;
    const y = (e.clientY - r.top) / r.height - 0.5;
    word.style.setProperty('--ry', (x * MAX * 2).toFixed(2) + 'deg');
    word.style.setProperty('--rx', (-y * MAX * 2).toFixed(2) + 'deg');
  }

  // 離れたら正面に戻す
  function reset() {
    word.style.setProperty('--rx', '0deg');
    word.style.setProperty('--ry', '0deg');
  }

  stage.addEventListener('pointermove', onMove);
  stage.addEventListener('pointerleave', reset);
})();

🤖 AIエージェント用プロンプト

このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「擬似3D押し出し文字」の効果を追加してください。

# 追加してほしい効果
擬似3D押し出し文字(タイポグラフィ)
多層 text-shadow で立体的に押し出した文字を作り、マウス追従でわずかに傾けます。レトロでインパクトのある見出しに使えます。

# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<main class="stage">
  <h1 class="extrude" data-text="RETRO">RETRO</h1>
  <p class="cap">多重 text-shadow による擬似3D押し出し</p>
</main>

【CSS】
* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  min-height: 360px;
  display: grid;
  place-items: center;
  background:
    radial-gradient(800px 500px at 50% 30%, #ff9e6d 0%, #ff5d8f 55%, #8b3ffd 100%);
  font-family: "Arial Black", "Segoe UI", system-ui, sans-serif;
  overflow: hidden;
  padding: 24px;
}

.stage {
  text-align: center;
  /* マウス追従でわずかに傾けるための起点 */
  perspective: 700px;
}

.extrude {
  font-size: clamp(60px, 17vw, 140px);
  font-weight: 900;
  letter-spacing: 0.04em;
  color: #fdf2e9;
  /* 影を何層も重ねて奥行きのある押し出しを表現 */
  text-shadow:
    1px 1px 0 #c2410c,
    2px 2px 0 #c2410c,
    3px 3px 0 #b03309,
    4px 4px 0 #b03309,
    5px 5px 0 #9a2c08,
    6px 6px 0 #9a2c08,
    7px 7px 0 #842506,
    8px 8px 14px rgba(0,0,0,0.4);
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .12s ease-out;
  transform-style: preserve-3d;
}

.cap {
  margin-top: 30px;
  font-family: "Segoe UI", system-ui, sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: rgba(255,255,255,0.85);
}

【JavaScript】
// マウス位置に応じて3D文字をわずかに傾ける
(function () {
  const stage = document.querySelector('.stage');
  const word = document.querySelector('.extrude');
  if (!stage || !word) return; // null安全

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

  const MAX = 14; // 最大傾き角(度)

  // ポインタの相対位置を-1..1に正規化して回転量に変換
  function onMove(e) {
    const r = stage.getBoundingClientRect();
    const x = (e.clientX - r.left) / r.width - 0.5;
    const y = (e.clientY - r.top) / r.height - 0.5;
    word.style.setProperty('--ry', (x * MAX * 2).toFixed(2) + 'deg');
    word.style.setProperty('--rx', (-y * MAX * 2).toFixed(2) + 'deg');
  }

  // 離れたら正面に戻す
  function reset() {
    word.style.setProperty('--rx', '0deg');
    word.style.setProperty('--ry', '0deg');
  }

  stage.addEventListener('pointermove', onMove);
  stage.addEventListener('pointerleave', reset);
})();

# 外部ライブラリ
なし(追加ライブラリ不要)

# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。