ブラーイン出現
見出しや要素を blur(12px)+scale+opacity 0 の状態から、鮮明・等倍へ連続して立ち上げる登場演出。要素ごとに時間差を付けてフォーカスが合う瞬間を演出します。ヒーローや見出しの初動に。
ライブデモ
使用例(お題: カフェ 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で提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。