浮遊ピル型ヘッダー
画面上端から少し浮かせた、角丸+影のカプセル状ヘッダー。スクロールすると幅が締まって中央に寄ります。モダンなブランドサイトやポートフォリオで人気の“浮いている”ナビです。
ライブデモ
使用例(お題: カフェ MOON BREW)
この技法を「カフェ MOON BREW」というテーマのダミーサイトで実際に使った例です。
HTML
<!-- MOON BREW:カフェの浮遊ピル型ヘッダー -->
<div class="hpf-frame">
<header class="hpf-head" id="hpfHead">
<a class="hpf-logo" href="#" onclick="return false">☕ MOON BREW</a>
<nav class="hpf-nav">
<a href="#" onclick="return false">メニュー</a>
<a href="#" onclick="return false">豆</a>
<a href="#" onclick="return false">店舗</a>
</nav>
<button class="hpf-cta" type="button">予約</button>
</header>
<div class="hpf-scroll" id="hpfScroll">
<section class="hpf-hero">
<h1>夜にひらく、珈琲店</h1>
<p>浮いた角丸ナビ。スクロールで幅が締まって中央に寄ります。</p>
</section>
<section class="hpf-body">
<p>深夜焙煎の一杯と、静かな時間を。月替わりのシングルオリジンを店頭・オンラインで。</p>
<p>スクロールするとピル型ヘッダーが引き締まり、軽やかな余白の中に浮かびます。</p>
<p>このデモは自動でゆっくり往復し、締まる→戻るの動きを実演します。</p>
</section>
</div>
</div>
CSS
/* MOON BREW(カフェ):浮遊ピル型ヘッダーの再スキン */
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.hpf-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: #17110a; }
.hpf-head {
position: absolute; z-index: 10; top: 16px; left: 50%; transform: translateX(-50%);
width: calc(100% - 32px); max-width: 860px;
display: flex; align-items: center; gap: 18px; height: 52px; padding: 0 14px 0 20px; border-radius: 16px;
background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.18);
-webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
box-shadow: 0 14px 40px rgba(0,0,0,.3); color: #fff;
transition: max-width .35s ease, top .35s ease, background .35s ease, box-shadow .35s ease, border-radius .35s ease;
}
.hpf-head.is-stuck { max-width: 540px; top: 10px; background: rgba(40,28,16,.85); border-radius: 999px; box-shadow: 0 10px 30px rgba(0,0,0,.45); }
.hpf-logo { font-size: 17px; font-weight: 800; color: #fff; text-decoration: none; }
.hpf-nav { display: flex; gap: 2px; margin-left: auto; }
.hpf-nav a { color: rgba(255,255,255,.88); text-decoration: none; font-size: 13px; font-weight: 600; padding: 7px 12px; border-radius: 999px; transition: background .2s ease; }
.hpf-nav a:hover { background: rgba(255,255,255,.16); }
.hpf-cta { font: inherit; font-size: 12.5px; font-weight: 700; color: #17110a; background: #e0a458; border: none; padding: 9px 16px; border-radius: 999px; cursor: pointer; transition: transform .15s ease; }
.hpf-cta:hover { transform: translateY(-1px); }
.hpf-scroll { height: 100%; overflow-y: auto; scrollbar-width: thin; }
.hpf-hero { min-height: 300px; display: grid; place-content: center; text-align: center; color: #fff; padding: 96px 24px 40px; background: radial-gradient(120% 120% at 50% 0%, #5a3a1c 0%, #17110a 70%); }
.hpf-hero h1 { margin: 0; font-size: 30px; font-weight: 800; font-family: "Hiragino Mincho ProN", serif; }
.hpf-hero p { margin: 12px 0 0; font-size: 14px; opacity: .82; }
.hpf-body { background: #f7f2e9; color: #4a3320; padding: 30px 26px 80px; line-height: 1.85; }
.hpf-body p { max-width: 560px; margin: 0 auto 18px; }
@media (prefers-reduced-motion: reduce) { .hpf-head, .hpf-cta { transition: none; } }
JavaScript
// (デモと同じフックを流用)スクロールでピル型ヘッダーを締める
(() => {
const sc = document.getElementById('hpfScroll');
const head = document.getElementById('hpfHead');
if (!sc || !head) return;
const apply = () => head.classList.toggle('is-stuck', sc.scrollTop > 40);
let ticking = false;
sc.addEventListener('scroll', () => { if (ticking) return; ticking = true; requestAnimationFrame(() => { apply(); ticking = false; }); }, { passive: true });
apply();
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
let auto = !reduce, dir = 1;
['wheel', 'touchstart', 'pointerdown'].forEach(ev => sc.addEventListener(ev, () => { auto = false; }, { passive: true }));
if (auto) {
setTimeout(function step() {
if (!auto) return;
sc.scrollTop += dir * 1.6;
if (sc.scrollTop >= 170) dir = -1; else if (sc.scrollTop <= 0) dir = 1;
requestAnimationFrame(step);
}, 900);
}
})();
実装ガイド
使いどころ
モダンなブランドサイトやポートフォリオに。画面上端から浮かせた角丸+影のカプセル型ヘッダーで、スクロールすると幅が締まって中央に寄ります。
実装時の注意点
常に中央配置(left:50%+translateX(-50%))で、is-stuck 時に max-width と top、背景・角丸・影をまとめて切り替えます。位置を transform 固定にしているため幅アニメーションが滑らかです。
対応ブラウザ
backdrop-filter(-webkit- 併記)・transform・transition は全モダンブラウザ対応。未対応環境でも半透明背景で成立します。
よくある失敗
浮かせる分、ヒーロー側に上部余白を確保しないと内容と重なります。幅可変は max-width で行い、left/right を直接アニメーションしない方が滑らか。モバイルでは浮遊幅を画面幅に近づけ、はみ出しを防ぎます。
応用例
スクロールで透明→ソリッド、ナビをアイコン化、中央にロゴを残して両脇を畳む、影の強さをスクロール量に連動させるなどの展開ができます。
コード
HTML
<!-- 画面から浮いた角丸ピル型ヘッダー(スクロールで締まる) -->
<div class="hpf-frame">
<header class="hpf-head" id="hpfHead">
<a class="hpf-logo" href="#" onclick="return false">◉ Orbit</a>
<nav class="hpf-nav">
<a href="#" onclick="return false">製品</a>
<a href="#" onclick="return false">設計</a>
<a href="#" onclick="return false">価格</a>
</nav>
<button class="hpf-cta" type="button">始める</button>
</header>
<div class="hpf-scroll" id="hpfScroll">
<section class="hpf-hero">
<h1>浮遊するピル型ヘッダー</h1>
<p>上端から浮いた角丸ナビ。スクロールすると幅が締まって中央に寄ります。</p>
</section>
<section class="hpf-body">
<p>ピル型ヘッダーは余白の中に浮くことで、軽やかでモダンな印象を与えます。近年のブランドサイトで人気の表現です。</p>
<p>スクロール量が閾値を超えると <code>is-stuck</code> が付き、幅・位置・影がまとめて切り替わります。</p>
<p>このデモは自動でゆっくり往復し、締まる→戻るの動きを実演します。</p>
</section>
</div>
</div>
CSS
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.hpf-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: #0c0f1a; }
/* 浮遊するピル型ヘッダー(常に中央、スクロールで幅が締まる) */
.hpf-head {
position: absolute; z-index: 10; top: 16px; left: 50%; transform: translateX(-50%);
width: calc(100% - 32px); max-width: 860px;
display: flex; align-items: center; gap: 18px;
height: 52px; padding: 0 14px 0 20px;
border-radius: 16px;
background: rgba(255,255,255,.1);
border: 1px solid rgba(255,255,255,.16);
-webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
box-shadow: 0 14px 40px rgba(0,0,0,.3);
color: #fff;
transition: max-width .35s ease, top .35s ease, background .35s ease, box-shadow .35s ease, border-radius .35s ease;
}
.hpf-head.is-stuck {
max-width: 540px; top: 10px;
background: rgba(16,18,32,.82);
border-radius: 999px;
box-shadow: 0 10px 30px rgba(0,0,0,.45);
}
.hpf-logo { font-size: 17px; font-weight: 800; color: #fff; text-decoration: none; }
.hpf-nav { display: flex; gap: 2px; margin-left: auto; }
.hpf-nav a { color: rgba(255,255,255,.86); text-decoration: none; font-size: 13px; font-weight: 600; padding: 7px 12px; border-radius: 999px; transition: background .2s ease; }
.hpf-nav a:hover { background: rgba(255,255,255,.14); }
.hpf-cta { font: inherit; font-size: 12.5px; font-weight: 700; color: #0c0f1a; background: #fff; border: none; padding: 9px 16px; border-radius: 999px; cursor: pointer; transition: transform .15s ease; }
.hpf-cta:hover { transform: translateY(-1px); }
.hpf-scroll { height: 100%; overflow-y: auto; scrollbar-width: thin; }
.hpf-hero {
min-height: 300px; display: grid; place-content: center; text-align: center; color: #fff; padding: 96px 24px 40px;
background: radial-gradient(120% 120% at 50% 0%, #3b2f80 0%, #0c0f1a 70%);
}
.hpf-hero h1 { margin: 0; font-size: 30px; font-weight: 800; }
.hpf-hero p { margin: 12px 0 0; font-size: 14px; opacity: .82; }
.hpf-body { background: #f6f7fb; color: #232842; padding: 30px 26px 80px; line-height: 1.85; }
.hpf-body p { max-width: 560px; margin: 0 auto 18px; }
.hpf-body code { background: rgba(99,102,241,.12); color: #4f46e5; padding: 1px 6px; border-radius: 5px; font-size: .92em; }
@media (prefers-reduced-motion: reduce) { .hpf-head, .hpf-cta { transition: none; } }
JavaScript
// スクロールでピル型ヘッダーを締める(中央寄せ・幅縮小)
(() => {
const sc = document.getElementById('hpfScroll');
const head = document.getElementById('hpfHead');
if (!sc || !head) return;
const apply = () => head.classList.toggle('is-stuck', sc.scrollTop > 40);
let ticking = false;
sc.addEventListener('scroll', () => {
if (ticking) return; ticking = true;
requestAnimationFrame(() => { apply(); ticking = false; });
}, { passive: true });
apply();
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
let auto = !reduce, dir = 1;
['wheel', 'touchstart', 'pointerdown'].forEach(ev => sc.addEventListener(ev, () => { auto = false; }, { passive: true }));
if (auto) {
setTimeout(function step() {
if (!auto) return;
sc.scrollTop += dir * 1.6;
if (sc.scrollTop >= 170) dir = -1; else if (sc.scrollTop <= 0) dir = 1;
requestAnimationFrame(step);
}, 900);
}
})();
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「浮遊ピル型ヘッダー」の効果を追加してください。
# 追加してほしい効果
浮遊ピル型ヘッダー(ヘッダー)
画面上端から少し浮かせた、角丸+影のカプセル状ヘッダー。スクロールすると幅が締まって中央に寄ります。モダンなブランドサイトやポートフォリオで人気の“浮いている”ナビです。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- 画面から浮いた角丸ピル型ヘッダー(スクロールで締まる) -->
<div class="hpf-frame">
<header class="hpf-head" id="hpfHead">
<a class="hpf-logo" href="#" onclick="return false">◉ Orbit</a>
<nav class="hpf-nav">
<a href="#" onclick="return false">製品</a>
<a href="#" onclick="return false">設計</a>
<a href="#" onclick="return false">価格</a>
</nav>
<button class="hpf-cta" type="button">始める</button>
</header>
<div class="hpf-scroll" id="hpfScroll">
<section class="hpf-hero">
<h1>浮遊するピル型ヘッダー</h1>
<p>上端から浮いた角丸ナビ。スクロールすると幅が締まって中央に寄ります。</p>
</section>
<section class="hpf-body">
<p>ピル型ヘッダーは余白の中に浮くことで、軽やかでモダンな印象を与えます。近年のブランドサイトで人気の表現です。</p>
<p>スクロール量が閾値を超えると <code>is-stuck</code> が付き、幅・位置・影がまとめて切り替わります。</p>
<p>このデモは自動でゆっくり往復し、締まる→戻るの動きを実演します。</p>
</section>
</div>
</div>
【CSS】
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.hpf-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: #0c0f1a; }
/* 浮遊するピル型ヘッダー(常に中央、スクロールで幅が締まる) */
.hpf-head {
position: absolute; z-index: 10; top: 16px; left: 50%; transform: translateX(-50%);
width: calc(100% - 32px); max-width: 860px;
display: flex; align-items: center; gap: 18px;
height: 52px; padding: 0 14px 0 20px;
border-radius: 16px;
background: rgba(255,255,255,.1);
border: 1px solid rgba(255,255,255,.16);
-webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
box-shadow: 0 14px 40px rgba(0,0,0,.3);
color: #fff;
transition: max-width .35s ease, top .35s ease, background .35s ease, box-shadow .35s ease, border-radius .35s ease;
}
.hpf-head.is-stuck {
max-width: 540px; top: 10px;
background: rgba(16,18,32,.82);
border-radius: 999px;
box-shadow: 0 10px 30px rgba(0,0,0,.45);
}
.hpf-logo { font-size: 17px; font-weight: 800; color: #fff; text-decoration: none; }
.hpf-nav { display: flex; gap: 2px; margin-left: auto; }
.hpf-nav a { color: rgba(255,255,255,.86); text-decoration: none; font-size: 13px; font-weight: 600; padding: 7px 12px; border-radius: 999px; transition: background .2s ease; }
.hpf-nav a:hover { background: rgba(255,255,255,.14); }
.hpf-cta { font: inherit; font-size: 12.5px; font-weight: 700; color: #0c0f1a; background: #fff; border: none; padding: 9px 16px; border-radius: 999px; cursor: pointer; transition: transform .15s ease; }
.hpf-cta:hover { transform: translateY(-1px); }
.hpf-scroll { height: 100%; overflow-y: auto; scrollbar-width: thin; }
.hpf-hero {
min-height: 300px; display: grid; place-content: center; text-align: center; color: #fff; padding: 96px 24px 40px;
background: radial-gradient(120% 120% at 50% 0%, #3b2f80 0%, #0c0f1a 70%);
}
.hpf-hero h1 { margin: 0; font-size: 30px; font-weight: 800; }
.hpf-hero p { margin: 12px 0 0; font-size: 14px; opacity: .82; }
.hpf-body { background: #f6f7fb; color: #232842; padding: 30px 26px 80px; line-height: 1.85; }
.hpf-body p { max-width: 560px; margin: 0 auto 18px; }
.hpf-body code { background: rgba(99,102,241,.12); color: #4f46e5; padding: 1px 6px; border-radius: 5px; font-size: .92em; }
@media (prefers-reduced-motion: reduce) { .hpf-head, .hpf-cta { transition: none; } }
【JavaScript】
// スクロールでピル型ヘッダーを締める(中央寄せ・幅縮小)
(() => {
const sc = document.getElementById('hpfScroll');
const head = document.getElementById('hpfHead');
if (!sc || !head) return;
const apply = () => head.classList.toggle('is-stuck', sc.scrollTop > 40);
let ticking = false;
sc.addEventListener('scroll', () => {
if (ticking) return; ticking = true;
requestAnimationFrame(() => { apply(); ticking = false; });
}, { passive: true });
apply();
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
let auto = !reduce, dir = 1;
['wheel', 'touchstart', 'pointerdown'].forEach(ev => sc.addEventListener(ev, () => { auto = false; }, { passive: true }));
if (auto) {
setTimeout(function step() {
if (!auto) return;
sc.scrollTop += dir * 1.6;
if (sc.scrollTop >= 170) dir = -1; else if (sc.scrollTop <= 0) dir = 1;
requestAnimationFrame(step);
}, 900);
}
})();
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。