ブラーイン出現

見出しや要素を blur(12px)+scale+opacity 0 の状態から、鮮明・等倍へ連続して立ち上げる登場演出。要素ごとに時間差を付けてフォーカスが合う瞬間を演出します。ヒーローや見出しの初動に。

#animation#blur#reveal#keyframes

ライブデモ

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

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

HTML
<!-- MOON BREW:ヒーロー見出しのブラーイン出現 -->
<section class="bi-stage">
  <div class="bi-overlay"></div>
  <header class="bi-nav">
    <div class="bi-brand" data-bi style="--d:0s"><span class="bi-cup">☕</span> MOON BREW</div>
    <button class="bi-nav-btn" data-bi style="--d:0.1s" type="button">ご予約</button>
  </header>

  <div class="bi-hero">
    <span class="bi-eyebrow" data-bi style="--d:0.2s">月夜のスペシャルティコーヒー</span>
    <h1 class="bi-title">
      <span data-bi style="--d:0.35s">静かな夜に、</span>
      <span data-bi style="--d:0.55s">一杯の灯りを。</span>
    </h1>
    <p class="bi-lead" data-bi style="--d:0.8s">深煎りの香りと、ゆっくり流れる時間。<br>今日のあなたに、ちょうどいい温度を。</p>
    <div class="bi-cta" data-bi style="--d:1s">
      <button class="bi-primary" type="button">メニューを見る</button>
      <button class="bi-ghost" id="biReplay" type="button">⟳ もう一度</button>
    </div>
  </div>
</section>
CSS
/* MOON BREW:ヒーロー要素のブラーイン出現 */
:root {
  --cream: #f5ede1;
  --brown: #2b1d12;
  --amber: #c98a3b;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  height: 400px;
  font-family: "Hiragino Mincho ProN", "Yu Mincho", "Segoe UI", serif;
  color: var(--cream);
  overflow: hidden;
}

.bi-stage {
  position: relative;
  height: 400px;
  padding: 18px 30px;
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(180deg, rgba(20, 12, 6, 0.2), rgba(20, 12, 6, 0.78)),
    url("https://picsum.photos/720/400?random=61") center/cover no-repeat;
}
.bi-overlay {
  position: absolute; inset: 0;
  background: radial-gradient(120% 100% at 20% 30%, rgba(201, 138, 59, 0.18), transparent 60%);
  pointer-events: none;
}

.bi-nav { position: relative; display: flex; align-items: center; justify-content: space-between; }
.bi-brand { font-size: 16px; font-weight: 800; letter-spacing: 0.08em; }
.bi-cup { font-size: 14px; }
.bi-nav-btn {
  font-family: inherit; font-size: 12px; font-weight: 700;
  padding: 7px 16px; border-radius: 999px; cursor: pointer;
  color: var(--brown); background: var(--cream); border: none;
}

.bi-hero { position: relative; flex: 1; display: flex; flex-direction: column; justify-content: center; max-width: 440px; }
.bi-eyebrow {
  align-self: flex-start;
  font-size: 11px; letter-spacing: 0.16em;
  padding: 4px 12px; border-radius: 999px;
  background: rgba(245, 237, 225, 0.14);
  margin-bottom: 14px;
}
.bi-title { margin: 0 0 14px; font-size: 36px; font-weight: 800; line-height: 1.25; letter-spacing: 0.02em; }
.bi-title span { display: block; }
.bi-lead { margin: 0 0 20px; font-size: 13px; line-height: 1.9; color: rgba(245, 237, 225, 0.85); }

.bi-cta { display: flex; gap: 10px; }
.bi-primary, .bi-ghost {
  font-family: inherit; font-size: 13px; font-weight: 700;
  padding: 10px 20px; border-radius: 999px; cursor: pointer;
}
.bi-primary { border: none; color: var(--cream); background: var(--amber); box-shadow: 0 10px 24px -8px rgba(201, 138, 59, 0.7); }
.bi-ghost { background: transparent; color: var(--cream); border: 1px solid rgba(245, 237, 225, 0.4); }

/* ブラーイン本体:JSで is-in を付与すると鮮明・等倍へ立ち上がる */
[data-bi] {
  opacity: 0;
  filter: blur(12px);
  transform: scale(1.06) translateY(8px);
}
[data-bi].is-in {
  opacity: 1;
  filter: blur(0);
  transform: none;
  /* 要素ごとに --d 分だけ遅らせてフォーカスが合う瞬間を演出 */
  transition:
    opacity 0.7s ease var(--d, 0s),
    filter 0.7s ease var(--d, 0s),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0s);
}

@media (prefers-reduced-motion: reduce) {
  [data-bi] { opacity: 1; filter: none; transform: none; }
  [data-bi].is-in { transition: none; }
}
JavaScript
// MOON BREW:ヒーロー要素をブラーから時間差で立ち上げる
(() => {
  const targets = Array.from(document.querySelectorAll("[data-bi]"));
  const replay = document.getElementById("biReplay");
  if (!targets.length) return; // null安全

  // 一度クリア → 次フレームで is-in を付けて遷移を起こす
  const play = () => {
    targets.forEach((el) => el.classList.remove("is-in"));
    requestAnimationFrame(() => {
      requestAnimationFrame(() => {
        targets.forEach((el) => el.classList.add("is-in"));
      });
    });
  };

  play(); // 初回出現
  if (replay) replay.addEventListener("click", play);
})();

コード

HTML
<!-- ブラーイン出現:blur+scale+opacity から鮮明へ立ち上がる連続演出 -->
<div class="blur-stage">
  <div class="blur-group" id="blurGroup">
    <p class="blur-line blur-eyebrow" data-blur>FOCUS IN</p>
    <h2 class="blur-line blur-title" data-blur>ピントが合う瞬間</h2>
    <p class="blur-line blur-sub" data-blur>blur(12px) から鮮明へ、要素ごとに時間差で立ち上がります。</p>
    <div class="blur-line blur-chips" data-blur>
      <span class="blur-chip">blur</span>
      <span class="blur-chip">scale</span>
      <span class="blur-chip">opacity</span>
    </div>
  </div>
  <button class="blur-btn" id="blurReplay" type="button">⟳ リプレイ</button>
</div>
CSS
/* 各行を blur+scale+opacity 0 から鮮明へ立ち上げる登場演出 */
:root {
  --dur: .9s;          /* 1行の演出時間 */
  --stagger: .14s;     /* 行ごとの時間差 */
  --accent: #ff7eb3;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  min-height: 360px;
  display: grid;
  place-items: center;
  font-family: "Segoe UI", "Hiragino Sans", "Yu Gothic UI", system-ui, sans-serif;
  background:
    radial-gradient(120% 120% at 50% 0%, #241a2e 0%, #0d0a14 72%);
  color: #f3eefb;
}
.blur-stage {
  width: min(440px, 90vw);
  padding: 22px;
  text-align: center;
}
.blur-group { display: grid; gap: 12px; }

/* 共通:演出前の状態(ぼけ・縮小・透明・少し下) */
.blur-line {
  margin: 0;
  filter: blur(12px);
  opacity: 0;
  transform: translateY(10px) scale(.94);
}
/* 再生クラス付与でキーフレーム発火。--i で行ごとに遅延 */
.blur-group.play .blur-line {
  animation: blurIn var(--dur) cubic-bezier(.2,.7,.2,1) both;
  animation-delay: calc(var(--i, 0) * var(--stagger));
}

@keyframes blurIn {
  0%   { filter: blur(12px); opacity: 0;  transform: translateY(10px) scale(.94); }
  60%  { filter: blur(2px);  opacity: 1;  transform: translateY(0)    scale(1.01); }
  100% { filter: blur(0);    opacity: 1;  transform: translateY(0)    scale(1); }
}

.blur-eyebrow {
  font-size: 11px;
  letter-spacing: .28em;
  color: var(--accent);
  font-family: "Consolas", "SFMono-Regular", monospace;
}
.blur-title {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: .02em;
  background: linear-gradient(120deg, #fff, #ffd5e8 60%, #b6e3ff);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.blur-sub {
  font-size: 13px;
  line-height: 1.7;
  color: #c8c0d8;
}
.blur-chips {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 2px;
}
.blur-chip {
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255,126,179,.14);
  border: 1px solid rgba(255,126,179,.35);
  color: #ffd5e8;
  font-family: "Consolas", "SFMono-Regular", monospace;
}

.blur-btn {
  margin-top: 22px;
  padding: 10px 18px;
  border: 1px solid rgba(255,126,179,.45);
  border-radius: 10px;
  background: rgba(255,126,179,.16);
  color: #fff0f6;
  font-size: 13px;
  cursor: pointer;
  transition: background .2s ease, transform .1s ease;
}
.blur-btn:hover { background: rgba(255,126,179,.3); }
.blur-btn:active { transform: scale(.97); }

/* モーション控えめ設定:演出を無効化し常に鮮明表示 */
@media (prefers-reduced-motion: reduce) {
  .blur-line { filter: none; opacity: 1; transform: none; }
  .blur-group.play .blur-line { animation: none; }
}
JavaScript
// ブラーイン出現:各行に時間差インデックスを与え、play クラスでキーフレーム再生
(() => {
  const group = document.getElementById('blurGroup');
  const replay = document.getElementById('blurReplay');
  if (!group) return; // null安全

  // 各行へ順番インデックス(--i)を付与=stagger の基準
  const lines = group.querySelectorAll('[data-blur]');
  lines.forEach((el, i) => el.style.setProperty('--i', i));

  // 再生:play を外して→リフロー→再付与でアニメを確実に再発火
  const play = () => {
    group.classList.remove('play');
    void group.offsetWidth; // リフロー強制
    requestAnimationFrame(() => group.classList.add('play'));
  };

  if (replay) replay.addEventListener('click', play);

  // 初期表示で自動再生
  requestAnimationFrame(play);
})();

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

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

# 追加してほしい効果
ブラーイン出現(アニメーション & トランジション)
見出しや要素を blur(12px)+scale+opacity 0 の状態から、鮮明・等倍へ連続して立ち上げる登場演出。要素ごとに時間差を付けてフォーカスが合う瞬間を演出します。ヒーローや見出しの初動に。

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

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- ブラーイン出現:blur+scale+opacity から鮮明へ立ち上がる連続演出 -->
<div class="blur-stage">
  <div class="blur-group" id="blurGroup">
    <p class="blur-line blur-eyebrow" data-blur>FOCUS IN</p>
    <h2 class="blur-line blur-title" data-blur>ピントが合う瞬間</h2>
    <p class="blur-line blur-sub" data-blur>blur(12px) から鮮明へ、要素ごとに時間差で立ち上がります。</p>
    <div class="blur-line blur-chips" data-blur>
      <span class="blur-chip">blur</span>
      <span class="blur-chip">scale</span>
      <span class="blur-chip">opacity</span>
    </div>
  </div>
  <button class="blur-btn" id="blurReplay" type="button">⟳ リプレイ</button>
</div>

【CSS】
/* 各行を blur+scale+opacity 0 から鮮明へ立ち上げる登場演出 */
:root {
  --dur: .9s;          /* 1行の演出時間 */
  --stagger: .14s;     /* 行ごとの時間差 */
  --accent: #ff7eb3;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  min-height: 360px;
  display: grid;
  place-items: center;
  font-family: "Segoe UI", "Hiragino Sans", "Yu Gothic UI", system-ui, sans-serif;
  background:
    radial-gradient(120% 120% at 50% 0%, #241a2e 0%, #0d0a14 72%);
  color: #f3eefb;
}
.blur-stage {
  width: min(440px, 90vw);
  padding: 22px;
  text-align: center;
}
.blur-group { display: grid; gap: 12px; }

/* 共通:演出前の状態(ぼけ・縮小・透明・少し下) */
.blur-line {
  margin: 0;
  filter: blur(12px);
  opacity: 0;
  transform: translateY(10px) scale(.94);
}
/* 再生クラス付与でキーフレーム発火。--i で行ごとに遅延 */
.blur-group.play .blur-line {
  animation: blurIn var(--dur) cubic-bezier(.2,.7,.2,1) both;
  animation-delay: calc(var(--i, 0) * var(--stagger));
}

@keyframes blurIn {
  0%   { filter: blur(12px); opacity: 0;  transform: translateY(10px) scale(.94); }
  60%  { filter: blur(2px);  opacity: 1;  transform: translateY(0)    scale(1.01); }
  100% { filter: blur(0);    opacity: 1;  transform: translateY(0)    scale(1); }
}

.blur-eyebrow {
  font-size: 11px;
  letter-spacing: .28em;
  color: var(--accent);
  font-family: "Consolas", "SFMono-Regular", monospace;
}
.blur-title {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: .02em;
  background: linear-gradient(120deg, #fff, #ffd5e8 60%, #b6e3ff);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.blur-sub {
  font-size: 13px;
  line-height: 1.7;
  color: #c8c0d8;
}
.blur-chips {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 2px;
}
.blur-chip {
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255,126,179,.14);
  border: 1px solid rgba(255,126,179,.35);
  color: #ffd5e8;
  font-family: "Consolas", "SFMono-Regular", monospace;
}

.blur-btn {
  margin-top: 22px;
  padding: 10px 18px;
  border: 1px solid rgba(255,126,179,.45);
  border-radius: 10px;
  background: rgba(255,126,179,.16);
  color: #fff0f6;
  font-size: 13px;
  cursor: pointer;
  transition: background .2s ease, transform .1s ease;
}
.blur-btn:hover { background: rgba(255,126,179,.3); }
.blur-btn:active { transform: scale(.97); }

/* モーション控えめ設定:演出を無効化し常に鮮明表示 */
@media (prefers-reduced-motion: reduce) {
  .blur-line { filter: none; opacity: 1; transform: none; }
  .blur-group.play .blur-line { animation: none; }
}

【JavaScript】
// ブラーイン出現:各行に時間差インデックスを与え、play クラスでキーフレーム再生
(() => {
  const group = document.getElementById('blurGroup');
  const replay = document.getElementById('blurReplay');
  if (!group) return; // null安全

  // 各行へ順番インデックス(--i)を付与=stagger の基準
  const lines = group.querySelectorAll('[data-blur]');
  lines.forEach((el, i) => el.style.setProperty('--i', i));

  // 再生:play を外して→リフロー→再付与でアニメを確実に再発火
  const play = () => {
    group.classList.remove('play');
    void group.offsetWidth; // リフロー強制
    requestAnimationFrame(() => group.classList.add('play'));
  };

  if (replay) replay.addEventListener('click', play);

  // 初期表示で自動再生
  requestAnimationFrame(play);
})();

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

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