Cookie同意バー
画面下に固定し、Cookie利用への同意・設定・拒否を促すバナー。GDPR等への配慮で多くのサイトに必須の要素です。同意で畳まれ、設定で詳細選択へ。控えめな出現で本文を邪魔しません。
ライブデモ
使用例(お題: SaaS FlowDesk)
この技法を「SaaS FlowDesk」というテーマのダミーサイトで実際に使った例です。
HTML
<!-- FlowDesk:SaaSのCookie同意バー -->
<div class="sck-frame">
<div class="sck-stage">
<h1>段取りを、ひとつに。</h1>
<p>画面下から Cookie 同意バナーが現れます。</p>
</div>
<div class="sck-banner" id="sckBanner">
<span class="sck-ico" aria-hidden="true">🍪</span>
<p class="sck-txt">FlowDesk は利便性向上のため Cookie を使用します。<a href="#" onclick="return false">プライバシー</a></p>
<div class="sck-actions">
<button class="sck-btn sck-btn--ghost" id="sckSettings" type="button">設定</button>
<button class="sck-btn sck-btn--solid" id="sckAccept" type="button">すべて許可</button>
</div>
<button class="sck-close" id="sckClose" type="button" aria-label="閉じる">✕</button>
</div>
</div>
CSS
/* FlowDesk(SaaS):Cookie同意バーの再スキン */
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.sck-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: linear-gradient(135deg, #e9edff, #f6f7fc); }
.sck-stage { display: grid; place-content: center; height: 100%; text-align: center; color: #1f2547; padding: 0 24px; }
.sck-stage h1 { margin: 0; font-size: 26px; font-weight: 800; }
.sck-stage p { margin: 12px 0 0; font-size: 13px; line-height: 1.8; color: #6a7090; }
.sck-banner { position: absolute; left: 16px; right: 16px; bottom: 16px; z-index: 10; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 16px 18px; border-radius: 14px; background: #fff; border: 1px solid #e3e7f2; box-shadow: 0 16px 40px rgba(20,30,80,.16); transform: translateY(160%); opacity: 0; transition: transform .45s cubic-bezier(.2,.8,.2,1), opacity .3s ease; }
.sck-banner.is-shown { transform: translateY(0); opacity: 1; }
.sck-ico { font-size: 22px; }
.sck-txt { margin: 0; flex: 1; min-width: 180px; font-size: 12.5px; color: #4a4f63; line-height: 1.6; }
.sck-txt a { color: #3b5bff; }
.sck-actions { display: flex; gap: 8px; }
.sck-btn { font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer; padding: 9px 16px; border-radius: 9px; transition: transform .15s ease, filter .15s ease; }
.sck-btn--ghost { background: #eef1f9; border: 1px solid #dfe3f0; color: #4a4f63; }
.sck-btn--ghost:hover { background: #e6eaf6; }
.sck-btn--solid { background: #3b5bff; border: none; color: #fff; }
.sck-btn--solid:hover { filter: brightness(1.08); transform: translateY(-1px); }
.sck-close { background: none; border: none; cursor: pointer; color: #9aa1b8; font-size: 13px; padding: 4px; }
.sck-close:hover { color: #4a4f63; }
@media (prefers-reduced-motion: reduce) { .sck-banner, .sck-btn { transition: none; } }
JavaScript
// (デモと同じフックを流用)同意バーの出現/畳み+自動実演
(() => {
const banner = document.getElementById('sckBanner');
if (!banner) return;
const show = (v) => banner.classList.toggle('is-shown', v);
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
['sckAccept', 'sckClose'].forEach(id => { const b = document.getElementById(id); if (b) b.addEventListener('click', () => { auto = false; show(false); }); });
const settings = document.getElementById('sckSettings');
if (settings) settings.addEventListener('click', () => { auto = false; });
setTimeout(() => show(true), 1000);
if (auto) {
let shown = true;
const tick = () => { if (!auto) return; shown = !shown; show(shown); setTimeout(tick, shown ? 3000 : 1600); };
setTimeout(tick, 3400);
}
})();
実装ガイド
使いどころ
GDPR等への配慮で多くのサイトに必須。画面下に固定し、Cookie利用への同意・設定・拒否を促すバナーです。
実装時の注意点
バナーは translateY+opacity で下からスッと出現し、同意/閉じるで畳まれます。プレビューでは自動で出る→畳むを繰り返します。実運用では同意状態を保存して再表示を抑えます。
対応ブラウザ
transform/opacity トランジションは全モダンブラウザ対応。JS は表示制御のみで軽量です。
よくある失敗
同意状態を localStorage/Cookie に保存し、再訪時に出さないこと。法令上は『拒否』も同等の操作性で提供する必要があります。本文やフォーカスを奪わない控えめな出現に。
応用例
詳細設定モーダル(カテゴリ別オンオフ)、地域判定での出し分け、同意ログの記録、フッターからの再表示リンクなどに展開できます。
コード
HTML
<!-- 下部固定のCookie同意バー -->
<div class="sck-frame">
<div class="sck-stage">
<h1>Cookie同意バー</h1>
<p>画面下から同意バナーが現れます。<br>「同意する」や ✕ で畳まれます(自動でも実演)。</p>
</div>
<div class="sck-banner" id="sckBanner">
<span class="sck-ico" aria-hidden="true">🍪</span>
<p class="sck-txt">当サイトは体験向上のため Cookie を使用します。<a href="#" onclick="return false">詳細</a></p>
<div class="sck-actions">
<button class="sck-btn sck-btn--ghost" id="sckSettings" type="button">設定</button>
<button class="sck-btn sck-btn--solid" id="sckAccept" type="button">同意する</button>
</div>
<button class="sck-close" id="sckClose" type="button" aria-label="閉じる">✕</button>
</div>
</div>
CSS
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.sck-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: linear-gradient(135deg, #eef1f7, #f7f8fc); }
.sck-stage { display: grid; place-content: center; height: 100%; text-align: center; color: #2a3050; padding: 0 24px; }
.sck-stage h1 { margin: 0; font-size: 26px; font-weight: 800; }
.sck-stage p { margin: 12px 0 0; font-size: 13px; line-height: 1.8; color: #6a7090; }
.sck-banner {
position: absolute; left: 16px; right: 16px; bottom: 16px; z-index: 10;
display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
padding: 16px 18px; border-radius: 14px;
background: #fff; border: 1px solid #e6e9f2; box-shadow: 0 16px 40px rgba(20,24,50,.16);
transform: translateY(160%); opacity: 0;
transition: transform .45s cubic-bezier(.2,.8,.2,1), opacity .3s ease;
}
.sck-banner.is-shown { transform: translateY(0); opacity: 1; }
.sck-ico { font-size: 22px; }
.sck-txt { margin: 0; flex: 1; min-width: 180px; font-size: 12.5px; color: #4a4f63; line-height: 1.6; }
.sck-txt a { color: #4f46e5; }
.sck-actions { display: flex; gap: 8px; }
.sck-btn { font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer; padding: 9px 16px; border-radius: 9px; transition: transform .15s ease, filter .15s ease; }
.sck-btn--ghost { background: #f1f3f9; border: 1px solid #e2e5ef; color: #4a4f63; }
.sck-btn--ghost:hover { background: #e9ecf5; }
.sck-btn--solid { background: #4f46e5; border: none; color: #fff; }
.sck-btn--solid:hover { filter: brightness(1.08); transform: translateY(-1px); }
.sck-close { background: none; border: none; cursor: pointer; color: #9aa1b1; font-size: 13px; padding: 4px; }
.sck-close:hover { color: #4a4f63; }
@media (prefers-reduced-motion: reduce) { .sck-banner, .sck-btn { transition: none; } }
JavaScript
// 同意バーの出現/畳み。プレビューでは自動で出る→畳むを繰り返す
(() => {
const banner = document.getElementById('sckBanner');
if (!banner) return;
const show = (v) => banner.classList.toggle('is-shown', v);
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
['sckAccept', 'sckClose'].forEach(id => {
const b = document.getElementById(id);
if (b) b.addEventListener('click', () => { auto = false; show(false); });
});
const settings = document.getElementById('sckSettings');
if (settings) settings.addEventListener('click', () => { auto = false; });
// 初回出現
setTimeout(() => show(true), 1000);
// 自動デモ:畳む→再表示
if (auto) {
let shown = true;
const tick = () => { if (!auto) return; shown = !shown; show(shown); setTimeout(tick, shown ? 3000 : 1600); };
setTimeout(tick, 3400);
}
})();
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「Cookie同意バー」の効果を追加してください。
# 追加してほしい効果
Cookie同意バー(追従ウィジェット)
画面下に固定し、Cookie利用への同意・設定・拒否を促すバナー。GDPR等への配慮で多くのサイトに必須の要素です。同意で畳まれ、設定で詳細選択へ。控えめな出現で本文を邪魔しません。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- 下部固定のCookie同意バー -->
<div class="sck-frame">
<div class="sck-stage">
<h1>Cookie同意バー</h1>
<p>画面下から同意バナーが現れます。<br>「同意する」や ✕ で畳まれます(自動でも実演)。</p>
</div>
<div class="sck-banner" id="sckBanner">
<span class="sck-ico" aria-hidden="true">🍪</span>
<p class="sck-txt">当サイトは体験向上のため Cookie を使用します。<a href="#" onclick="return false">詳細</a></p>
<div class="sck-actions">
<button class="sck-btn sck-btn--ghost" id="sckSettings" type="button">設定</button>
<button class="sck-btn sck-btn--solid" id="sckAccept" type="button">同意する</button>
</div>
<button class="sck-close" id="sckClose" type="button" aria-label="閉じる">✕</button>
</div>
</div>
【CSS】
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.sck-frame { position: relative; width: 100%; height: 380px; overflow: hidden; background: linear-gradient(135deg, #eef1f7, #f7f8fc); }
.sck-stage { display: grid; place-content: center; height: 100%; text-align: center; color: #2a3050; padding: 0 24px; }
.sck-stage h1 { margin: 0; font-size: 26px; font-weight: 800; }
.sck-stage p { margin: 12px 0 0; font-size: 13px; line-height: 1.8; color: #6a7090; }
.sck-banner {
position: absolute; left: 16px; right: 16px; bottom: 16px; z-index: 10;
display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
padding: 16px 18px; border-radius: 14px;
background: #fff; border: 1px solid #e6e9f2; box-shadow: 0 16px 40px rgba(20,24,50,.16);
transform: translateY(160%); opacity: 0;
transition: transform .45s cubic-bezier(.2,.8,.2,1), opacity .3s ease;
}
.sck-banner.is-shown { transform: translateY(0); opacity: 1; }
.sck-ico { font-size: 22px; }
.sck-txt { margin: 0; flex: 1; min-width: 180px; font-size: 12.5px; color: #4a4f63; line-height: 1.6; }
.sck-txt a { color: #4f46e5; }
.sck-actions { display: flex; gap: 8px; }
.sck-btn { font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer; padding: 9px 16px; border-radius: 9px; transition: transform .15s ease, filter .15s ease; }
.sck-btn--ghost { background: #f1f3f9; border: 1px solid #e2e5ef; color: #4a4f63; }
.sck-btn--ghost:hover { background: #e9ecf5; }
.sck-btn--solid { background: #4f46e5; border: none; color: #fff; }
.sck-btn--solid:hover { filter: brightness(1.08); transform: translateY(-1px); }
.sck-close { background: none; border: none; cursor: pointer; color: #9aa1b1; font-size: 13px; padding: 4px; }
.sck-close:hover { color: #4a4f63; }
@media (prefers-reduced-motion: reduce) { .sck-banner, .sck-btn { transition: none; } }
【JavaScript】
// 同意バーの出現/畳み。プレビューでは自動で出る→畳むを繰り返す
(() => {
const banner = document.getElementById('sckBanner');
if (!banner) return;
const show = (v) => banner.classList.toggle('is-shown', v);
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
['sckAccept', 'sckClose'].forEach(id => {
const b = document.getElementById(id);
if (b) b.addEventListener('click', () => { auto = false; show(false); });
});
const settings = document.getElementById('sckSettings');
if (settings) settings.addEventListener('click', () => { auto = false; });
// 初回出現
setTimeout(() => show(true), 1000);
// 自動デモ:畳む→再表示
if (auto) {
let shown = true;
const tick = () => { if (!auto) return; shown = !shown; show(shown); setTimeout(tick, shown ? 3000 : 1600); };
setTimeout(tick, 3400);
}
})();
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。