ポップオーバー Popover
要素の近くにフローティングで表示される小さなパネル。追加情報やアクションを提供する。
ライブデモ
ユーザー情報
山田太郎
フロントエンドエンジニア
東京都在住・5年の経験
ソースコード
<div class="demo-popover-area">
<div class="demo-popover-wrap">
<button class="demo-popover-trigger" data-target="demo-pop-1">クリックで表示</button>
<div class="demo-popover-content" id="demo-pop-1">
<div class="demo-popover-arrow"></div>
<div class="demo-popover-header">ユーザー情報</div>
<div class="demo-popover-body">
<p><strong>山田太郎</strong></p>
<p>フロントエンドエンジニア</p>
<p style="font-size:12px;color:#6b7280;">東京都在住・5年の経験</p>
</div>
<div class="demo-popover-footer">
<button class="demo-popover-action">プロフィールを見る</button>
</div>
</div>
</div>
<div class="demo-popover-wrap">
<button class="demo-popover-trigger demo-popover-trigger-outline" data-target="demo-pop-2">アクション</button>
<div class="demo-popover-content" id="demo-pop-2">
<div class="demo-popover-arrow"></div>
<div class="demo-popover-menu">
<button class="demo-popover-menuitem">✎ 編集</button>
<button class="demo-popover-menuitem">⎘ コピー</button>
<button class="demo-popover-menuitem demo-popover-menuitem-danger">✖ 削除</button>
</div>
</div>
</div>
</div>.demo-popover-area { display: flex; gap: 16px; flex-wrap: wrap; padding: 20px 0; align-items: flex-start; justify-content: center; min-height: 250px; }
.demo-popover-wrap { position: relative; display: inline-block; }
.demo-popover-trigger {
padding: 8px 16px; border: none; border-radius: 8px; font-size: 13px;
font-weight: 600; cursor: pointer; background: var(--ui-primary); color: #fff;
transition: opacity 0.2s;
}
.demo-popover-trigger:hover { opacity: 0.9; }
.demo-popover-trigger-outline {
background: transparent; color: var(--ui-primary);
border: 2px solid var(--ui-primary);
}
.demo-popover-trigger-outline:hover { background: color-mix(in srgb, var(--ui-primary) 8%, transparent); opacity: 1; }
.demo-popover-content {
display: none; position: absolute; top: calc(100% + 10px); left: 50%; transform: translateX(-50%);
background: #fff; border: 1px solid #e5e7eb; border-radius: 12px;
box-shadow: 0 8px 24px rgba(0,0,0,0.12); z-index: 20; min-width: 200px;
animation: demo-popover-in 0.2s ease;
}
.demo-popover-content.open { display: block !important; }
@keyframes demo-popover-in { from { opacity: 0; transform: translateX(-50%) translateY(-4px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }
.demo-popover-arrow {
position: absolute; top: -6px; left: 50%; transform: translateX(-50%) rotate(45deg);
width: 12px; height: 12px; background: #fff; border-left: 1px solid #e5e7eb; border-top: 1px solid #e5e7eb;
}
.demo-popover-header { padding: 12px 16px 8px; font-size: 12px; font-weight: 600; color: #6b7280; text-transform: uppercase; letter-spacing: 0.5px; }
.demo-popover-body { padding: 0 16px 12px; font-size: 13px; color: #333; line-height: 1.5; }
.demo-popover-body p { margin: 2px 0; }
.demo-popover-footer { padding: 8px 16px 12px; }
.demo-popover-action {
width: 100%; padding: 8px; border: none; border-radius: 6px; font-size: 13px;
font-weight: 600; cursor: pointer; background: var(--ui-primary); color: #fff;
transition: opacity 0.2s;
}
.demo-popover-action:hover { opacity: 0.9; }
.demo-popover-menu { padding: 6px; }
.demo-popover-menuitem {
display: block; width: 100%; padding: 8px 12px; border: none; background: none;
text-align: left; font-size: 13px; color: #333; border-radius: 6px;
cursor: pointer; transition: background 0.15s;
}
.demo-popover-menuitem:hover { background: color-mix(in srgb, var(--ui-primary) 10%, transparent); color: var(--ui-primary); }
.demo-popover-menuitem-danger:hover { background: #fef2f2; color: #ef4444; }(function(){
document.querySelectorAll('.demo-popover-trigger').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.stopPropagation();
var target = document.getElementById(this.dataset.target);
var isOpen = target.classList.contains('open');
document.querySelectorAll('.demo-popover-content.open').forEach(function(p) { p.classList.remove('open'); });
if (!isOpen) target.classList.add('open');
});
});
document.addEventListener('click', function(e) {
if (!e.target.closest('.demo-popover-content')) {
document.querySelectorAll('.demo-popover-content.open').forEach(function(p) { p.classList.remove('open'); });
}
});
})();AIプロンプト
Basic
ポップオーバーをHTML/CSS/JSで作ってください。ボタンをクリックするとフローティングパネルが表示されます。
Custom
以下の仕様でポップオーバーを実装してください。 - クリックで表示/非表示の切り替え - 矢印付きのフローティングパネル - プライマリカラー: #2563eb - ヘッダー・ボディ・フッター構成 - 外側クリックで閉じる - フェードイン/アウトアニメーション - メニュー型のバリエーション(アクションリスト)
Advanced
アクセシビリティ対応のポップオーバーを実装してください。 - aria-expanded / aria-haspopup / aria-controls の適切な設定 - Escapeキーで閉じる - フォーカストラップ(ポップオーバー内でTabキーが循環) - Floating UI ライクな自動位置調整(画面端でフリップ) - ネスト対応(ポップオーバー内にポップオーバー) - ホバー表示モードのオプション - prefers-reduced-motion 対応 - スクリーンリーダーで内容の読み上げ対応