Global Attribute
NEW
The popover attribute transforms any element into a popover that can be toggled open and closed. Popovers are displayed above other page content, have automatic light dismiss behavior, and are managed by the browser’s top layer, making them perfect for tooltips, menus, dialogs, and disclosure widgets.
< element popover > Content </ element >
< element popover = " auto " > Content </ element >
< element popover = " manual " > Content </ element >
Value Description Dismiss Behavior auto (default)Auto-dismiss popover Closes when clicking outside, pressing Esc, or opening another auto popover manualManual popover Only closes via explicit action (button click or JavaScript)
Interactive code playground requires JavaScript. Here's the code:
<!DOCTYPE html>
<html>
<head>
<style>
body { padding: 40px; font-family: Arial, sans-serif; }
button {
padding: 12px 24px;
background: #3b82f6;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
}
button:hover { background: #2563eb; }
[popover] {
padding: 20px;
border: 2px solid #e2e8f0;
border-radius: 12px;
background: white;
box-shadow: 0 10px 40px rgba(0,0,0,0.15);
max-width: 300px;
}
[popover] h3 {
margin: 0 0 10px;
color: #1e293b;
}
[popover] p {
margin: 0;
color: #64748b;
line-height: 1.6;
}
[popover]::backdrop {
background: rgba(0, 0, 0, 0.2);
}
</style>
</head>
<body>
<h2>Popover Demo</h2>
<p>Click the button to show a popover:</p>
<button popovertarget="my-popover">Show Popover</button>
<div id="my-popover" popover>
<h3>🎉 This is a Popover!</h3>
<p>Click outside, press Esc, or click the button again to close it.</p>
</div>
</body>
</html>
Interactive code playground requires JavaScript. Here's the code:
<!DOCTYPE html>
<html>
<head>
<style>
.demo { padding: 30px; font-family: Arial, sans-serif; }
.demo-section {
margin: 30px 0;
padding: 20px;
background: #f8fafc;
border-radius: 12px;
}
.demo-section h3 { margin-top: 0; color: #1e293b; }
button {
padding: 10px 20px;
background: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
margin: 5px;
}
button:hover { background: #2563eb; }
.close-btn {
background: #ef4444;
float: right;
padding: 4px 12px;
font-size: 14px;
}
.close-btn:hover { background: #dc2626; }
[popover] {
padding: 20px;
border: 2px solid #e2e8f0;
border-radius: 8px;
background: white;
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
max-width: 350px;
}
[popover="auto"] {
border-color: #3b82f6;
}
[popover="manual"] {
border-color: #f59e0b;
}
[popover] h4 {
margin: 0 0 10px;
color: #1e293b;
}
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
margin-left: 8px;
}
.badge-auto {
background: #dbeafe;
color: #1e40af;
}
.badge-manual {
background: #fef3c7;
color: #92400e;
}
</style>
</head>
<body>
<div class="demo">
<h2>Auto vs Manual Popovers</h2>
<div class="demo-section">
<h3>Auto Popover <span class="badge badge-auto">popover="auto"</span></h3>
<p>Automatically closes when:</p>
<ul>
<li>Clicking outside the popover</li>
<li>Pressing the Escape key</li>
<li>Opening another auto popover</li>
</ul>
<button popovertarget="auto-popover">Open Auto Popover</button>
</div>
<div class="demo-section">
<h3>Manual Popover <span class="badge badge-manual">popover="manual"</span></h3>
<p>Only closes when:</p>
<ul>
<li>Explicitly closed via button</li>
<li>Closed via JavaScript</li>
</ul>
<p><strong>Note:</strong> Clicking outside or Esc key won't close it!</p>
<button popovertarget="manual-popover">Open Manual Popover</button>
</div>
<!-- Auto Popover -->
<div id="auto-popover" popover="auto">
<h4>Auto Popover</h4>
<p>Try clicking outside or pressing Escape to close this popover.</p>
<p style="color: #64748b; font-size: 14px;">It will close automatically!</p>
</div>
<!-- Manual Popover -->
<div id="manual-popover" popover="manual">
<button class="close-btn" popovertarget="manual-popover" popovertargetaction="hide">×</button>
<h4>Manual Popover</h4>
<p>This popover won't close when clicking outside or pressing Escape.</p>
<p style="color: #64748b; font-size: 14px;">You must click the × button to close it!</p>
</div>
</div>
</body>
</html>
Interactive code playground requires JavaScript. Here's the code:
<!DOCTYPE html>
<html>
<head>
<style>
body { padding: 40px; font-family: Arial, sans-serif; }
.tooltip-demo {
max-width: 600px;
margin: 40px 0;
line-height: 2;
}
.has-tooltip {
color: #3b82f6;
text-decoration: underline;
text-decoration-style: dotted;
cursor: help;
}
.tooltip {
padding: 8px 12px;
background: #1e293b;
color: white;
border-radius: 6px;
font-size: 14px;
max-width: 200px;
border: none;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.tooltip::backdrop {
background: transparent;
}
</style>
</head>
<body>
<h2>Tooltip with Popover</h2>
<div class="tooltip-demo">
<p>
The <span class="has-tooltip" popovertarget="tooltip-html">HTML</span>
language is used to structure web pages. It works together with
<span class="has-tooltip" popovertarget="tooltip-css">CSS</span>
for styling and
<span class="has-tooltip" popovertarget="tooltip-js">JavaScript</span>
for interactivity.
</p>
</div>
<div id="tooltip-html" popover class="tooltip">
HTML stands for HyperText Markup Language
</div>
<div id="tooltip-css" popover class="tooltip">
CSS stands for Cascading Style Sheets
</div>
<div id="tooltip-js" popover class="tooltip">
JavaScript is a programming language for web browsers
</div>
</body>
</html>
Interactive code playground requires JavaScript. Here's the code:
<!DOCTYPE html>
<html>
<head>
<style>
body { padding: 40px; font-family: Arial, sans-serif; }
.menu-button {
padding: 10px 20px;
background: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
display: inline-flex;
align-items: center;
gap: 8px;
}
.menu-button:hover { background: #2563eb; }
.menu {
padding: 8px;
border: 2px solid #e2e8f0;
border-radius: 8px;
background: white;
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
min-width: 200px;
margin: 0;
}
.menu-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
cursor: pointer;
border-radius: 4px;
transition: background 0.2s;
color: #1e293b;
}
.menu-item:hover {
background: #f1f5f9;
}
.menu-separator {
height: 1px;
background: #e2e8f0;
margin: 5px 0;
}
</style>
</head>
<body>
<h2>Menu Popover</h2>
<button class="menu-button" popovertarget="menu">
<span>Options</span>
<span>▼</span>
</button>
<div id="menu" popover class="menu">
<div class="menu-item" onclick="alert('Edit clicked')">
<span>✏️</span>
<span>Edit</span>
</div>
<div class="menu-item" onclick="alert('Copy clicked')">
<span>📋</span>
<span>Copy</span>
</div>
<div class="menu-item" onclick="alert('Share clicked')">
<span>🔗</span>
<span>Share</span>
</div>
<div class="menu-separator"></div>
<div class="menu-item" onclick="alert('Delete clicked')" style="color: #ef4444;">
<span>🗑️</span>
<span>Delete</span>
</div>
</div>
</body>
</html>
Interactive code playground requires JavaScript. Here's the code:
<!DOCTYPE html>
<html>
<head>
<style>
body { padding: 40px; font-family: Arial, sans-serif; }
.notification-btn {
position: relative;
padding: 10px 20px;
background: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
}
.badge-count {
position: absolute;
top: -8px;
right: -8px;
background: #ef4444;
color: white;
border-radius: 10px;
padding: 2px 6px;
font-size: 12px;
font-weight: bold;
}
.notifications {
padding: 0;
border: 2px solid #e2e8f0;
border-radius: 8px;
background: white;
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
width: 350px;
max-height: 400px;
overflow-y: auto;
}
.notifications-header {
padding: 15px;
border-bottom: 2px solid #e2e8f0;
font-weight: bold;
color: #1e293b;
display: flex;
justify-content: space-between;
align-items: center;
}
.notification-item {
padding: 15px;
border-bottom: 1px solid #f1f5f9;
cursor: pointer;
transition: background 0.2s;
}
.notification-item:hover {
background: #f8fafc;
}
.notification-item:last-child {
border-bottom: none;
}
.notification-title {
font-weight: bold;
color: #1e293b;
margin-bottom: 4px;
}
.notification-text {
color: #64748b;
font-size: 14px;
margin-bottom: 4px;
}
.notification-time {
color: #94a3b8;
font-size: 12px;
}
.mark-read {
background: none;
border: none;
color: #3b82f6;
cursor: pointer;
font-size: 14px;
padding: 0;
}
</style>
</head>
<body>
<h2>Notification Popover</h2>
<button class="notification-btn" popovertarget="notifications">
🔔 Notifications
<span class="badge-count">3</span>
</button>
<div id="notifications" popover class="notifications">
<div class="notifications-header">
<span>Notifications</span>
<button class="mark-read">Mark all as read</button>
</div>
<div class="notification-item">
<div class="notification-title">New message from Sarah</div>
<div class="notification-text">Hey, are you available for a call?</div>
<div class="notification-time">5 minutes ago</div>
</div>
<div class="notification-item">
<div class="notification-title">Project update</div>
<div class="notification-text">The deployment was successful!</div>
<div class="notification-time">1 hour ago</div>
</div>
<div class="notification-item">
<div class="notification-title">New comment on your post</div>
<div class="notification-text">John commented: "Great work!"</div>
<div class="notification-time">2 hours ago</div>
</div>
</div>
</body>
</html>
Popovers are displayed in the browser’s top layer :
Always rendered on top of other content
Not affected by parent z-index or overflow
Automatically manages stacking order
Has a ::backdrop pseudo-element
background : rgba ( 0 , 0 , 0 , 0.3 );
Auto popovers close when:
Clicking outside the popover
Pressing the Escape key
Opening another auto popover
Clicking the trigger button again
Manual popovers only close via:
Explicit button with popovertargetaction="hide"
JavaScript: element.hidePopover()
const popover = document . getElementById ( ' my-popover ' );
if ( popover . matches ( ' :popover-open ' )) {
console . log ( ' Popover is open ' );
popover . addEventListener ( ' beforetoggle ' , ( event ) => {
console . log ( ' State: ' , event . newState ); // "open" or "closed"
popover . addEventListener ( ' toggle ' , ( event ) => {
console . log ( ' Popover toggled ' );
background : rgba ( 0 , 0 , 0 , 0.5 );
backdrop-filter : blur ( 3 px );
transform : translateY ( -10 px );
transform : translateY ( 0 );
<!-- Auto: For menus, tooltips, dropdowns -->
< div popover = " auto " > Menu items... </ div >
<!-- Manual: For notifications that shouldn't auto-dismiss -->
< div popover = " manual " > Important message... </ div >
< div id = " manual-popup " popover = " manual " >
< button popovertarget = " manual-popup " popovertargetaction = " hide " >
< div id = " menu " popover role = " menu " >
< button role = " menuitem " > Option 1 </ button >
< button role = " menuitem " > Option 2 </ button >
transition : opacity 0.3 s , transform 0.3 s ;
[ popover ] :not (: popover-open ) {
Popovers have built-in keyboard support:
Escape : Closes auto popovers
Tab : Focus moves within popover
Focus trap : Browser manages focus
< button popovertarget = " menu " aria-label = " Open menu " >
< div id = " menu " popover role = " menu " aria-label = " Options menu " >
Browser Support Chrome 114+ Edge 114+ Safari 17+ Firefox 125+ (behind flag)