言語・地域セレクタ付きフッター
言語・地域・通貨を選べるセレクタを備えたフッター。グローバル展開のECやSaaSで、訪問者に合わせた表示へ切り替える導線を最下部に置けます。ドロップダウンで省スペースにまとめます。
ライブデモ
使用例(お題: SaaS FlowDesk)
この技法を「SaaS FlowDesk」というテーマのダミーサイトで実際に使った例です。
HTML
<!-- FlowDesk:グローバルSaaSの言語・地域セレクタ付きフッター -->
<footer class="flc">
<div class="flc-top">
<div class="flc-brand">
<a class="flc-logo" href="#" onclick="return false">◇ FlowDesk</a>
<p class="flc-tag">世界中のチームへ。</p>
</div>
<nav class="flc-cols">
<div class="flc-col"><p class="flc-col__h">製品</p><a href="#" onclick="return false">機能</a><a href="#" onclick="return false">料金</a></div>
<div class="flc-col"><p class="flc-col__h">会社</p><a href="#" onclick="return false">採用</a><a href="#" onclick="return false">規約</a></div>
</nav>
</div>
<div class="flc-bar">
<div class="flc-selectors">
<div class="flc-sel" id="flcLang">
<button class="flc-sel__btn" type="button" aria-expanded="false"><span class="flc-glyph">🌐</span><b id="flcLangLabel">日本語</b><span class="flc-caret">▾</span></button>
<ul class="flc-sel__menu" role="menu">
<li role="menuitem" data-v="日本語">日本語</li>
<li role="menuitem" data-v="English">English</li>
<li role="menuitem" data-v="Deutsch">Deutsch</li>
<li role="menuitem" data-v="Français">Français</li>
</ul>
</div>
<button class="flc-chip" type="button">地域:日本</button>
<button class="flc-chip" type="button">通貨:JPY ¥</button>
</div>
<span class="flc-copy">© 2026 FlowDesk Inc.</span>
</div>
</footer>
CSS
/* FlowDesk(SaaS):言語・地域セレクタ付きフッターの再スキン */
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.flc { width: 100%; min-height: 380px; display: flex; flex-direction: column; background: #0c1226; color: #d7dcec; }
.flc-top { flex: 1; display: flex; justify-content: space-between; gap: 24px; padding: 34px 30px; }
.flc-logo { font-size: 19px; font-weight: 800; color: #fff; text-decoration: none; }
.flc-tag { margin: 10px 0 0; font-size: 12.5px; color: #8a93b8; }
.flc-cols { display: flex; gap: 44px; }
.flc-col__h { margin: 0 0 10px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: #6c76a0; }
.flc-col a { display: block; color: #d7dcec; text-decoration: none; font-size: 13px; padding: 4px 0; transition: color .16s ease; }
.flc-col a:hover { color: #fff; }
.flc-bar { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 14px 30px; border-top: 1px solid #1d2442; }
.flc-selectors { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.flc-sel { position: relative; }
.flc-sel__btn { display: inline-flex; align-items: center; gap: 7px; font: inherit; font-size: 12.5px; color: #e7ebf5; background: #161d35; border: 1px solid #2a3252; border-radius: 9px; padding: 8px 12px; cursor: pointer; transition: border-color .2s ease; }
.flc-sel__btn:hover { border-color: #475180; }
.flc-sel__btn b { font-weight: 700; }
.flc-caret { font-size: 9px; opacity: .7; transition: transform .25s ease; }
.flc-sel.open .flc-caret { transform: rotate(180deg); }
.flc-sel__menu { position: absolute; left: 0; bottom: calc(100% + 6px); z-index: 10; list-style: none; margin: 0; padding: 6px; min-width: 150px; background: #161d35; border: 1px solid #2a3252; border-radius: 11px; box-shadow: 0 -14px 34px rgba(0,0,0,.45); opacity: 0; transform: translateY(6px); pointer-events: none; transition: opacity .2s ease, transform .2s ease; }
.flc-sel.open .flc-sel__menu { opacity: 1; transform: translateY(0); pointer-events: auto; }
.flc-sel__menu li { font-size: 13px; color: #d7dcec; padding: 9px 11px; border-radius: 8px; cursor: pointer; transition: background .15s ease; }
.flc-sel__menu li:hover { background: #232c4a; color: #fff; }
.flc-chip { font: inherit; font-size: 12.5px; color: #d7dcec; background: #161d35; border: 1px solid #2a3252; border-radius: 9px; padding: 8px 12px; cursor: pointer; transition: border-color .2s ease; }
.flc-chip:hover { border-color: #475180; color: #fff; }
.flc-copy { font-size: 12px; color: #6c76a0; }
@media (prefers-reduced-motion: reduce) { .flc-sel__menu, .flc-caret { transition: none; } }
JavaScript
// (デモと同じフックを流用)言語ドロップダウンの開閉+選択+自動実演
(() => {
const sel = document.getElementById('flcLang');
if (!sel) return;
const btn = sel.querySelector('.flc-sel__btn');
const label = document.getElementById('flcLangLabel');
const menu = sel.querySelector('.flc-sel__menu');
const setOpen = (open) => { sel.classList.toggle('open', open); if (btn) btn.setAttribute('aria-expanded', open ? 'true' : 'false'); };
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
if (btn) btn.addEventListener('click', () => { auto = false; setOpen(!sel.classList.contains('open')); });
if (menu) menu.addEventListener('click', (e) => { const li = e.target.closest('li'); if (!li) return; auto = false; if (label) label.textContent = li.dataset.v || li.textContent; setOpen(false); });
if (auto) {
let open = false;
const tick = () => { if (!auto) return; open = !open; setOpen(open); setTimeout(tick, open ? 2000 : 1600); };
setTimeout(tick, 1300);
}
})();
実装ガイド
使いどころ
グローバル展開のEC・SaaSのフッターに。言語・地域・通貨を切り替えるセレクタを最下部にまとめ、訪問者に合わせた表示へ誘導します。
実装時の注意点
言語はカスタムドロップダウン(上方向に開く)で、選択するとボタンのラベルが変わります。地域・通貨はチップ表示。JS は開閉と選択、プレビュー用の自動開閉です。
対応ブラウザ
position・transition・flexbox で全モダンブラウザ対応。フッター最下部のため、メニューは上方向(bottom:100%)に開きます。
よくある失敗
選択を localStorage や Cookie に保存し再訪時に反映を。フッター下端ではメニューを上開きにしないと画面外に出ます。外側クリックや Esc で閉じる導線、キーボード操作対応を加えるとより堅牢です。
応用例
実際の i18n と連動した表示切替、地域に応じた通貨/税の自動切替、国旗アイコンの併記、検索可能な言語リストなどに展開できます。
コード
HTML
<!-- 言語・地域・通貨セレクタ付きフッター -->
<footer class="flc">
<div class="flc-top">
<div class="flc-brand">
<a class="flc-logo" href="#" onclick="return false">◍ Globe</a>
<p class="flc-tag">世界中のチームへ。</p>
</div>
<nav class="flc-cols">
<div class="flc-col"><p class="flc-col__h">製品</p><a href="#" onclick="return false">概要</a><a href="#" onclick="return false">料金</a></div>
<div class="flc-col"><p class="flc-col__h">会社</p><a href="#" onclick="return false">採用</a><a href="#" onclick="return false">規約</a></div>
</nav>
</div>
<div class="flc-bar">
<div class="flc-selectors">
<div class="flc-sel" id="flcLang">
<button class="flc-sel__btn" type="button" aria-expanded="false"><span class="flc-glyph">🌐</span><b id="flcLangLabel">日本語</b><span class="flc-caret">▾</span></button>
<ul class="flc-sel__menu" role="menu">
<li role="menuitem" data-v="日本語">日本語</li>
<li role="menuitem" data-v="English">English</li>
<li role="menuitem" data-v="한국어">한국어</li>
<li role="menuitem" data-v="中文">中文</li>
</ul>
</div>
<button class="flc-chip" type="button">地域:日本</button>
<button class="flc-chip" type="button">通貨:JPY ¥</button>
</div>
<span class="flc-copy">© 2026 Globe Inc.</span>
</div>
</footer>
CSS
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.flc { width: 100%; min-height: 380px; display: flex; flex-direction: column; background: #101418; color: #d7dce3; }
.flc-top { flex: 1; display: flex; justify-content: space-between; gap: 24px; padding: 34px 30px; }
.flc-logo { font-size: 19px; font-weight: 800; color: #fff; text-decoration: none; }
.flc-tag { margin: 10px 0 0; font-size: 12.5px; color: #8a93a0; }
.flc-cols { display: flex; gap: 44px; }
.flc-col__h { margin: 0 0 10px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: #6c7682; }
.flc-col a { display: block; color: #d7dce3; text-decoration: none; font-size: 13px; padding: 4px 0; transition: color .16s ease; }
.flc-col a:hover { color: #fff; }
.flc-bar { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 14px 30px; border-top: 1px solid #1d242b; }
.flc-selectors { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.flc-sel { position: relative; }
.flc-sel__btn { display: inline-flex; align-items: center; gap: 7px; font: inherit; font-size: 12.5px; color: #e7ebf0; background: #1a2128; border: 1px solid #2a323b; border-radius: 9px; padding: 8px 12px; cursor: pointer; transition: border-color .2s ease; }
.flc-sel__btn:hover { border-color: #475160; }
.flc-sel__btn b { font-weight: 700; }
.flc-caret { font-size: 9px; opacity: .7; transition: transform .25s ease; }
.flc-sel.open .flc-caret { transform: rotate(180deg); }
.flc-sel__menu {
position: absolute; left: 0; bottom: calc(100% + 6px); z-index: 10;
list-style: none; margin: 0; padding: 6px; min-width: 150px;
background: #1a2128; border: 1px solid #2a323b; border-radius: 11px;
box-shadow: 0 -14px 34px rgba(0,0,0,.45);
opacity: 0; transform: translateY(6px); pointer-events: none;
transition: opacity .2s ease, transform .2s ease;
}
.flc-sel.open .flc-sel__menu { opacity: 1; transform: translateY(0); pointer-events: auto; }
.flc-sel__menu li { font-size: 13px; color: #d7dce3; padding: 9px 11px; border-radius: 8px; cursor: pointer; transition: background .15s ease; }
.flc-sel__menu li:hover { background: #232c35; color: #fff; }
.flc-chip { font: inherit; font-size: 12.5px; color: #d7dce3; background: #1a2128; border: 1px solid #2a323b; border-radius: 9px; padding: 8px 12px; cursor: pointer; transition: border-color .2s ease; }
.flc-chip:hover { border-color: #475160; color: #fff; }
.flc-copy { font-size: 12px; color: #6c7682; }
@media (prefers-reduced-motion: reduce) { .flc-sel__menu, .flc-caret { transition: none; } }
JavaScript
// 言語ドロップダウンの開閉+選択。プレビューでは自動でも開閉を実演
(() => {
const sel = document.getElementById('flcLang');
if (!sel) return;
const btn = sel.querySelector('.flc-sel__btn');
const label = document.getElementById('flcLangLabel');
const menu = sel.querySelector('.flc-sel__menu');
const setOpen = (open) => { sel.classList.toggle('open', open); if (btn) btn.setAttribute('aria-expanded', open ? 'true' : 'false'); };
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
if (btn) btn.addEventListener('click', () => { auto = false; setOpen(!sel.classList.contains('open')); });
if (menu) menu.addEventListener('click', (e) => {
const li = e.target.closest('li'); if (!li) return;
auto = false;
if (label) label.textContent = li.dataset.v || li.textContent;
setOpen(false);
});
if (auto) {
let open = false;
const tick = () => { if (!auto) return; open = !open; setOpen(open); setTimeout(tick, open ? 2000 : 1600); };
setTimeout(tick, 1300);
}
})();
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「言語・地域セレクタ付きフッター」の効果を追加してください。
# 追加してほしい効果
言語・地域セレクタ付きフッター(フッター)
言語・地域・通貨を選べるセレクタを備えたフッター。グローバル展開のECやSaaSで、訪問者に合わせた表示へ切り替える導線を最下部に置けます。ドロップダウンで省スペースにまとめます。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- 言語・地域・通貨セレクタ付きフッター -->
<footer class="flc">
<div class="flc-top">
<div class="flc-brand">
<a class="flc-logo" href="#" onclick="return false">◍ Globe</a>
<p class="flc-tag">世界中のチームへ。</p>
</div>
<nav class="flc-cols">
<div class="flc-col"><p class="flc-col__h">製品</p><a href="#" onclick="return false">概要</a><a href="#" onclick="return false">料金</a></div>
<div class="flc-col"><p class="flc-col__h">会社</p><a href="#" onclick="return false">採用</a><a href="#" onclick="return false">規約</a></div>
</nav>
</div>
<div class="flc-bar">
<div class="flc-selectors">
<div class="flc-sel" id="flcLang">
<button class="flc-sel__btn" type="button" aria-expanded="false"><span class="flc-glyph">🌐</span><b id="flcLangLabel">日本語</b><span class="flc-caret">▾</span></button>
<ul class="flc-sel__menu" role="menu">
<li role="menuitem" data-v="日本語">日本語</li>
<li role="menuitem" data-v="English">English</li>
<li role="menuitem" data-v="한국어">한국어</li>
<li role="menuitem" data-v="中文">中文</li>
</ul>
</div>
<button class="flc-chip" type="button">地域:日本</button>
<button class="flc-chip" type="button">通貨:JPY ¥</button>
</div>
<span class="flc-copy">© 2026 Globe Inc.</span>
</div>
</footer>
【CSS】
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.flc { width: 100%; min-height: 380px; display: flex; flex-direction: column; background: #101418; color: #d7dce3; }
.flc-top { flex: 1; display: flex; justify-content: space-between; gap: 24px; padding: 34px 30px; }
.flc-logo { font-size: 19px; font-weight: 800; color: #fff; text-decoration: none; }
.flc-tag { margin: 10px 0 0; font-size: 12.5px; color: #8a93a0; }
.flc-cols { display: flex; gap: 44px; }
.flc-col__h { margin: 0 0 10px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: #6c7682; }
.flc-col a { display: block; color: #d7dce3; text-decoration: none; font-size: 13px; padding: 4px 0; transition: color .16s ease; }
.flc-col a:hover { color: #fff; }
.flc-bar { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 14px 30px; border-top: 1px solid #1d242b; }
.flc-selectors { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.flc-sel { position: relative; }
.flc-sel__btn { display: inline-flex; align-items: center; gap: 7px; font: inherit; font-size: 12.5px; color: #e7ebf0; background: #1a2128; border: 1px solid #2a323b; border-radius: 9px; padding: 8px 12px; cursor: pointer; transition: border-color .2s ease; }
.flc-sel__btn:hover { border-color: #475160; }
.flc-sel__btn b { font-weight: 700; }
.flc-caret { font-size: 9px; opacity: .7; transition: transform .25s ease; }
.flc-sel.open .flc-caret { transform: rotate(180deg); }
.flc-sel__menu {
position: absolute; left: 0; bottom: calc(100% + 6px); z-index: 10;
list-style: none; margin: 0; padding: 6px; min-width: 150px;
background: #1a2128; border: 1px solid #2a323b; border-radius: 11px;
box-shadow: 0 -14px 34px rgba(0,0,0,.45);
opacity: 0; transform: translateY(6px); pointer-events: none;
transition: opacity .2s ease, transform .2s ease;
}
.flc-sel.open .flc-sel__menu { opacity: 1; transform: translateY(0); pointer-events: auto; }
.flc-sel__menu li { font-size: 13px; color: #d7dce3; padding: 9px 11px; border-radius: 8px; cursor: pointer; transition: background .15s ease; }
.flc-sel__menu li:hover { background: #232c35; color: #fff; }
.flc-chip { font: inherit; font-size: 12.5px; color: #d7dce3; background: #1a2128; border: 1px solid #2a323b; border-radius: 9px; padding: 8px 12px; cursor: pointer; transition: border-color .2s ease; }
.flc-chip:hover { border-color: #475160; color: #fff; }
.flc-copy { font-size: 12px; color: #6c7682; }
@media (prefers-reduced-motion: reduce) { .flc-sel__menu, .flc-caret { transition: none; } }
【JavaScript】
// 言語ドロップダウンの開閉+選択。プレビューでは自動でも開閉を実演
(() => {
const sel = document.getElementById('flcLang');
if (!sel) return;
const btn = sel.querySelector('.flc-sel__btn');
const label = document.getElementById('flcLangLabel');
const menu = sel.querySelector('.flc-sel__menu');
const setOpen = (open) => { sel.classList.toggle('open', open); if (btn) btn.setAttribute('aria-expanded', open ? 'true' : 'false'); };
let auto = !matchMedia('(prefers-reduced-motion: reduce)').matches;
if (btn) btn.addEventListener('click', () => { auto = false; setOpen(!sel.classList.contains('open')); });
if (menu) menu.addEventListener('click', (e) => {
const li = e.target.closest('li'); if (!li) return;
auto = false;
if (label) label.textContent = li.dataset.v || li.textContent;
setOpen(false);
});
if (auto) {
let open = false;
const tick = () => { if (!auto) return; open = !open; setOpen(open); setTimeout(tick, open ? 2000 : 1600); };
setTimeout(tick, 1300);
}
})();
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。