検索バー展開ヘッダー
虫めがねアイコンをクリックすると、ナビの上をスライドして検索入力欄が伸びてくるヘッダー。普段はすっきり、必要なときだけ検索を前面に出せます。ECやメディアの回遊性を保ちつつ省スペースにできます。
ライブデモ
使用例(お題: SaaS FlowDesk)
この技法を「SaaS FlowDesk」というテーマのダミーサイトで実際に使った例です。
HTML
<!-- FlowDesk:ヘルプセンターの検索展開ヘッダー -->
<div class="hse-frame">
<header class="hse-head">
<a class="hse-logo" href="#" onclick="return false">◇ FlowDesk Help</a>
<nav class="hse-nav">
<a href="#" onclick="return false">ガイド</a>
<a href="#" onclick="return false">API</a>
<a href="#" onclick="return false">よくある質問</a>
</nav>
<form class="hse-search" id="hseSearch" onsubmit="return false">
<input class="hse-input" id="hseInput" type="search" placeholder="ヘルプ記事を検索…" aria-label="検索">
<button class="hse-btn" id="hseBtn" type="button" aria-label="検索を開く">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21 21l-4.3-4.3M11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
</button>
</form>
</header>
<div class="hse-stage">
<h1>お困りですか?</h1>
<p>右上の検索から、5,000本以上のヘルプ記事を探せます。</p>
</div>
</div>
CSS
/* FlowDesk(SaaS):検索バー展開ヘッダーの再スキン */
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.hse-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: radial-gradient(120% 120% at 50% 0%, #eaeeff, #f6f7fc 60%); }
.hse-head { display: flex; align-items: center; gap: 18px; height: 60px; padding: 0 22px; background: #fff; border-bottom: 1px solid #e7eaf3; }
.hse-logo { font-size: 18px; font-weight: 800; color: #1f2547; text-decoration: none; }
.hse-nav { display: flex; gap: 4px; }
.hse-nav a { color: #3a4060; text-decoration: none; font-size: 13.5px; font-weight: 600; padding: 7px 12px; border-radius: 8px; transition: background .2s ease; }
.hse-nav a:hover { background: #eef1fc; color: #3b5bff; }
.hse-search { display: flex; align-items: center; margin-left: auto; background: #eef1f9; border-radius: 999px; padding: 4px; }
.hse-input { font: inherit; font-size: 13.5px; color: #1f2547; width: 0; opacity: 0; padding: 0; border: none; background: transparent; outline: none; transition: width .35s cubic-bezier(.2,.8,.2,1), opacity .25s ease, padding .35s ease; }
.hse-search.open .hse-input { width: 220px; opacity: 1; padding: 8px 12px; }
.hse-input::placeholder { color: #9aa1b8; }
.hse-btn { flex: 0 0 auto; width: 38px; height: 38px; border: none; cursor: pointer; border-radius: 50%; background: #3b5bff; color: #fff; display: grid; place-items: center; transition: background .2s ease, transform .15s ease; }
.hse-btn svg { width: 18px; height: 18px; }
.hse-btn:hover { background: #2f49d8; transform: scale(1.05); }
.hse-search.open .hse-btn { background: #1f2547; }
.hse-stage { display: grid; place-content: center; height: calc(100% - 60px); text-align: center; color: #2a3050; padding: 0 24px; }
.hse-stage h1 { margin: 0; font-size: 26px; font-weight: 800; }
.hse-stage p { margin: 12px 0 0; font-size: 13px; line-height: 1.8; color: #6a7090; }
@media (prefers-reduced-motion: reduce) { .hse-input, .hse-btn { transition: none; } }
JavaScript
// (デモと同じフックを流用)検索アイコンで入力欄を開閉+自動実演
(() => {
const form = document.getElementById('hseSearch');
const btn = document.getElementById('hseBtn');
const input = document.getElementById('hseInput');
if (!form || !btn) return;
const set = (open, focus) => {
form.classList.toggle('open', open);
btn.setAttribute('aria-label', open ? '検索を閉じる' : '検索を開く');
if (open && focus && input) try { input.focus(); } catch (e) {}
};
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
btn.addEventListener('click', () => { auto = false; set(!form.classList.contains('open'), true); });
if (input) input.addEventListener('pointerdown', () => { auto = false; });
if (auto) {
let open = false;
const tick = () => { if (!auto) return; open = !open; set(open); setTimeout(tick, open ? 2400 : 1700); };
setTimeout(tick, 1100);
}
})();
実装ガイド
使いどころ
EC・メディア・ヘルプセンターなど検索が主要導線のサイトに。普段はアイコンだけ、必要なときにスライドで検索欄が伸びる省スペース型ヘッダーです。
実装時の注意点
入力欄を width:0→指定幅へトランジションし、opacity と padding も連動させて自然に開きます。開閉は is-open クラスのみで制御。自動デモ時は input.focus() を呼ばず、実クリック時だけフォーカスします(iframe内フォーカスで親がスクロールするのを防ぐため)。
対応ブラウザ
width/opacity のトランジションは全モダンブラウザで安定。type=search の装飾差はブラウザ毎にありますが動作に影響しません。
よくある失敗
幅をピクセル固定にすると狭い画面で溢れるため、max-width や vw も併用を。開いたら自動でフォーカスし、Esc や外側クリックで閉じる導線を用意するとUXが向上。プレースホルダだけで用途が伝わるよう文言を具体的に。
応用例
検索候補(サジェスト)パネルの追加、全画面検索オーバーレイへの拡張、ショートカット(/ キー)でのフォーカス、最近の検索履歴表示などに展開できます。
コード
HTML
<!-- アイコンから検索バーが伸びるヘッダー -->
<div class="hse-frame">
<header class="hse-head">
<a class="hse-logo" href="#" onclick="return false">Verge</a>
<nav class="hse-nav">
<a href="#" onclick="return false">製品</a>
<a href="#" onclick="return false">事例</a>
<a href="#" onclick="return false">料金</a>
<a href="#" onclick="return false">ブログ</a>
</nav>
<form class="hse-search" id="hseSearch" onsubmit="return false">
<input class="hse-input" id="hseInput" type="search" placeholder="製品・記事を検索…" aria-label="検索">
<button class="hse-btn" id="hseBtn" type="button" aria-label="検索を開く">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21 21l-4.3-4.3M11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
</button>
</form>
</header>
<div class="hse-stage">
<h1>検索バー展開ヘッダー</h1>
<p>右上のアイコンで検索欄がスライドして開きます。<br>(自動でも開閉を実演します)</p>
</div>
</div>
CSS
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.hse-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: #f5f6fa; }
.hse-head { display: flex; align-items: center; gap: 18px; height: 60px; padding: 0 22px; background: #fff; border-bottom: 1px solid #e8ebf3; }
.hse-logo { font-size: 19px; font-weight: 800; color: #1f2433; text-decoration: none; letter-spacing: -.01em; }
.hse-nav { display: flex; gap: 4px; }
.hse-nav a { color: #3a4060; text-decoration: none; font-size: 13.5px; font-weight: 600; padding: 7px 12px; border-radius: 8px; transition: background .2s ease; }
.hse-nav a:hover { background: #eef1fb; color: #4f46e5; }
/* 検索:アイコン+伸縮する入力欄 */
.hse-search { display: flex; align-items: center; margin-left: auto; background: #f1f3f9; border-radius: 999px; padding: 4px; }
.hse-input {
font: inherit; font-size: 13.5px; color: #1f2433;
width: 0; opacity: 0; padding: 0; border: none; background: transparent; outline: none;
transition: width .35s cubic-bezier(.2,.8,.2,1), opacity .25s ease, padding .35s ease;
}
.hse-search.open .hse-input { width: 220px; opacity: 1; padding: 8px 12px; }
.hse-input::placeholder { color: #9aa1b1; }
.hse-btn {
flex: 0 0 auto; width: 38px; height: 38px; border: none; cursor: pointer;
border-radius: 50%; background: #4f46e5; color: #fff; display: grid; place-items: center;
transition: background .2s ease, transform .15s ease;
}
.hse-btn svg { width: 18px; height: 18px; }
.hse-btn:hover { background: #4338ca; transform: scale(1.05); }
.hse-search.open .hse-btn { background: #1f2433; }
.hse-stage { display: grid; place-content: center; height: calc(100% - 60px); text-align: center; color: #2a3050; padding: 0 24px; }
.hse-stage h1 { margin: 0; font-size: 26px; font-weight: 800; }
.hse-stage p { margin: 12px 0 0; font-size: 13px; line-height: 1.8; color: #6a7090; }
@media (prefers-reduced-motion: reduce) { .hse-input, .hse-btn { transition: none; } }
JavaScript
// 検索アイコンで入力欄を開閉。プレビューでは自動でも実演
(() => {
const form = document.getElementById('hseSearch');
const btn = document.getElementById('hseBtn');
const input = document.getElementById('hseInput');
if (!form || !btn) return;
const set = (open, focus) => {
form.classList.toggle('open', open);
btn.setAttribute('aria-label', open ? '検索を閉じる' : '検索を開く');
if (open && focus && input) try { input.focus(); } catch (e) {}
};
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
btn.addEventListener('click', () => { auto = false; set(!form.classList.contains('open'), true); });
if (input) input.addEventListener('pointerdown', () => { auto = false; });
if (auto) {
let open = false;
const tick = () => { if (!auto) return; open = !open; set(open); setTimeout(tick, open ? 2400 : 1700); };
setTimeout(tick, 1100);
}
})();
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「検索バー展開ヘッダー」の効果を追加してください。
# 追加してほしい効果
検索バー展開ヘッダー(ヘッダー)
虫めがねアイコンをクリックすると、ナビの上をスライドして検索入力欄が伸びてくるヘッダー。普段はすっきり、必要なときだけ検索を前面に出せます。ECやメディアの回遊性を保ちつつ省スペースにできます。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- アイコンから検索バーが伸びるヘッダー -->
<div class="hse-frame">
<header class="hse-head">
<a class="hse-logo" href="#" onclick="return false">Verge</a>
<nav class="hse-nav">
<a href="#" onclick="return false">製品</a>
<a href="#" onclick="return false">事例</a>
<a href="#" onclick="return false">料金</a>
<a href="#" onclick="return false">ブログ</a>
</nav>
<form class="hse-search" id="hseSearch" onsubmit="return false">
<input class="hse-input" id="hseInput" type="search" placeholder="製品・記事を検索…" aria-label="検索">
<button class="hse-btn" id="hseBtn" type="button" aria-label="検索を開く">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21 21l-4.3-4.3M11 18a7 7 0 1 1 0-14 7 7 0 0 1 0 14Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
</button>
</form>
</header>
<div class="hse-stage">
<h1>検索バー展開ヘッダー</h1>
<p>右上のアイコンで検索欄がスライドして開きます。<br>(自動でも開閉を実演します)</p>
</div>
</div>
【CSS】
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.hse-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: #f5f6fa; }
.hse-head { display: flex; align-items: center; gap: 18px; height: 60px; padding: 0 22px; background: #fff; border-bottom: 1px solid #e8ebf3; }
.hse-logo { font-size: 19px; font-weight: 800; color: #1f2433; text-decoration: none; letter-spacing: -.01em; }
.hse-nav { display: flex; gap: 4px; }
.hse-nav a { color: #3a4060; text-decoration: none; font-size: 13.5px; font-weight: 600; padding: 7px 12px; border-radius: 8px; transition: background .2s ease; }
.hse-nav a:hover { background: #eef1fb; color: #4f46e5; }
/* 検索:アイコン+伸縮する入力欄 */
.hse-search { display: flex; align-items: center; margin-left: auto; background: #f1f3f9; border-radius: 999px; padding: 4px; }
.hse-input {
font: inherit; font-size: 13.5px; color: #1f2433;
width: 0; opacity: 0; padding: 0; border: none; background: transparent; outline: none;
transition: width .35s cubic-bezier(.2,.8,.2,1), opacity .25s ease, padding .35s ease;
}
.hse-search.open .hse-input { width: 220px; opacity: 1; padding: 8px 12px; }
.hse-input::placeholder { color: #9aa1b1; }
.hse-btn {
flex: 0 0 auto; width: 38px; height: 38px; border: none; cursor: pointer;
border-radius: 50%; background: #4f46e5; color: #fff; display: grid; place-items: center;
transition: background .2s ease, transform .15s ease;
}
.hse-btn svg { width: 18px; height: 18px; }
.hse-btn:hover { background: #4338ca; transform: scale(1.05); }
.hse-search.open .hse-btn { background: #1f2433; }
.hse-stage { display: grid; place-content: center; height: calc(100% - 60px); text-align: center; color: #2a3050; padding: 0 24px; }
.hse-stage h1 { margin: 0; font-size: 26px; font-weight: 800; }
.hse-stage p { margin: 12px 0 0; font-size: 13px; line-height: 1.8; color: #6a7090; }
@media (prefers-reduced-motion: reduce) { .hse-input, .hse-btn { transition: none; } }
【JavaScript】
// 検索アイコンで入力欄を開閉。プレビューでは自動でも実演
(() => {
const form = document.getElementById('hseSearch');
const btn = document.getElementById('hseBtn');
const input = document.getElementById('hseInput');
if (!form || !btn) return;
const set = (open, focus) => {
form.classList.toggle('open', open);
btn.setAttribute('aria-label', open ? '検索を閉じる' : '検索を開く');
if (open && focus && input) try { input.focus(); } catch (e) {}
};
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
btn.addEventListener('click', () => { auto = false; set(!form.classList.contains('open'), true); });
if (input) input.addEventListener('pointerdown', () => { auto = false; });
if (auto) {
let open = false;
const tick = () => { if (!auto) return; open = !open; set(open); setTimeout(tick, open ? 2400 : 1700); };
setTimeout(tick, 1100);
}
})();
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。