Global Attribute
NEW
The popovertargetaction attribute specifies what action a button should perform on a popover element: show it, hide it, or toggle it. It works in combination with the popovertarget attribute to provide fine-grained control over popover behavior.
< button popovertarget = " popover-id " popovertargetaction = " action " > Button </ button >
Value Description Behavior toggle (default)Toggle the popover Opens if closed, closes if open showShow the popover Only opens, won’t close if already open hideHide the popover Only closes, won’t open if already closed
Interactive code playground requires JavaScript. Here's the code:
<!DOCTYPE html>
<html>
<head>
<style>
body { padding: 40px; font-family: Arial, sans-serif; }
.button-group {
display: flex;
gap: 10px;
margin: 20px 0;
flex-wrap: wrap;
}
button {
padding: 12px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: transform 0.2s;
}
button:hover { transform: translateY(-2px); }
.btn-show {
background: #10b981;
color: white;
}
.btn-hide {
background: #ef4444;
color: white;
}
.btn-toggle {
background: #3b82f6;
color: white;
}
.popover-demo {
padding: 24px;
border: 2px solid #e2e8f0;
border-radius: 12px;
background: white;
box-shadow: 0 10px 40px rgba(0,0,0,0.15);
max-width: 350px;
}
.popover-demo h3 {
margin: 0 0 15px;
color: #1e293b;
}
.info-box {
background: #f1f5f9;
padding: 12px;
border-radius: 6px;
margin-bottom: 15px;
font-size: 14px;
color: #64748b;
}
</style>
</head>
<body>
<h2>popovertargetaction Values</h2>
<div class="info-box">
Try clicking the different buttons to see how each action works!
</div>
<div class="button-group">
<button
class="btn-show"
popovertarget="demo-popover"
popovertargetaction="show">
✓ Show
</button>
<button
class="btn-hide"
popovertarget="demo-popover"
popovertargetaction="hide">
✕ Hide
</button>
<button
class="btn-toggle"
popovertarget="demo-popover"
popovertargetaction="toggle">
⇄ Toggle
</button>
</div>
<div id="demo-popover" popover class="popover-demo">
<h3>Popover Content</h3>
<ul style="margin: 0; padding-left: 20px; color: #64748b;">
<li><strong>Show</strong>: Only opens the popover</li>
<li><strong>Hide</strong>: Only closes the popover</li>
<li><strong>Toggle</strong>: Opens if closed, closes if open</li>
</ul>
</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; }
.demo-section {
background: #f8fafc;
padding: 30px;
border-radius: 12px;
max-width: 600px;
}
button {
padding: 10px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: 600;
margin: 5px;
}
.open-btn {
background: #10b981;
color: white;
}
.open-btn:hover { background: #059669; }
.modal {
padding: 0;
border: none;
border-radius: 16px;
background: white;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
max-width: 450px;
width: 90%;
}
.modal::backdrop {
background: rgba(0, 0, 0, 0.5);
}
.modal-header {
background: #1e293b;
color: white;
padding: 20px;
border-radius: 16px 16px 0 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h3 {
margin: 0;
}
.close-btn {
background: transparent;
border: 2px solid white;
color: white;
padding: 6px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
.close-btn:hover {
background: rgba(255, 255, 255, 0.1);
}
.modal-body {
padding: 30px;
}
.modal-body p {
margin: 0 0 15px;
color: #64748b;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="demo-section">
<h2>Separate Open/Close Controls</h2>
<p>Use <code>show</code> and <code>hide</code> for explicit control:</p>
<button
class="open-btn"
popovertarget="settings-modal"
popovertargetaction="show">
Open Settings
</button>
</div>
<div id="settings-modal" popover="manual" class="modal">
<div class="modal-header">
<h3>Settings</h3>
<button
class="close-btn"
popovertarget="settings-modal"
popovertargetaction="hide">
Close ✕
</button>
</div>
<div class="modal-body">
<p><strong>Manual Popover:</strong> This popover uses popover="manual", so it requires explicit close buttons.</p>
<p>The close button uses <code>popovertargetaction="hide"</code> to dismiss the modal.</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; }
.controls {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.panel-btn {
padding: 10px 20px;
border: 2px solid #e2e8f0;
background: white;
border-radius: 6px;
cursor: pointer;
font-weight: 600;
color: #64748b;
transition: all 0.2s;
}
.panel-btn:hover {
border-color: #3b82f6;
color: #3b82f6;
}
[popover] {
padding: 24px;
border: 2px solid #e2e8f0;
border-radius: 12px;
background: white;
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
max-width: 400px;
margin-bottom: 10px;
}
[popover] h3 {
margin: 0 0 15px;
color: #1e293b;
}
[popover] p {
margin: 0;
color: #64748b;
line-height: 1.6;
}
.panel-A {
border-color: #3b82f6;
}
.panel-B {
border-color: #10b981;
}
.panel-C {
border-color: #f59e0b;
}
</style>
</head>
<body>
<h2>Multi-Panel Dashboard</h2>
<p>Show/hide different panels independently:</p>
<div class="controls">
<button
class="panel-btn"
popovertarget="panel-a"
popovertargetaction="toggle">
Panel A
</button>
<button
class="panel-btn"
popovertarget="panel-b"
popovertargetaction="toggle">
Panel B
</button>
<button
class="panel-btn"
popovertarget="panel-c"
popovertargetaction="toggle">
Panel C
</button>
</div>
<div id="panel-a" popover="manual" class="panel-A">
<h3>📊 Analytics Panel</h3>
<p>View your analytics and statistics here.</p>
<button popovertarget="panel-a" popovertargetaction="hide">Close</button>
</div>
<div id="panel-b" popover="manual" class="panel-B">
<h3>⚙️ Settings Panel</h3>
<p>Configure your account settings and preferences.</p>
<button popovertarget="panel-b" popovertargetaction="hide">Close</button>
</div>
<div id="panel-c" popover="manual" class="panel-C">
<h3>💬 Messages Panel</h3>
<p>Read and respond to your messages.</p>
<button popovertarget="panel-c" popovertargetaction="hide">Close</button>
</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; }
.wizard-container {
max-width: 600px;
margin: 0 auto;
}
.start-btn {
padding: 14px 28px;
background: #3b82f6;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
}
.start-btn:hover { background: #2563eb; }
.step {
padding: 30px;
border: 2px solid #e2e8f0;
border-radius: 12px;
background: white;
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
max-width: 500px;
}
.step::backdrop {
background: rgba(0, 0, 0, 0.5);
}
.step h3 {
margin: 0 0 15px;
color: #1e293b;
}
.step-content {
margin: 20px 0;
color: #64748b;
line-height: 1.6;
}
.step-actions {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
button {
padding: 10px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: 600;
}
.btn-next {
background: #3b82f6;
color: white;
}
.btn-prev {
background: #e2e8f0;
color: #1e293b;
}
.btn-finish {
background: #10b981;
color: white;
}
</style>
</head>
<body>
<div class="wizard-container">
<h2>Setup Wizard</h2>
<p>Complete the setup in three easy steps:</p>
<button
class="start-btn"
popovertarget="step1"
popovertargetaction="show">
Start Setup
</button>
<!-- Step 1 -->
<div id="step1" popover="manual" class="step">
<h3>Step 1: Account Info</h3>
<div class="step-content">
<p>Enter your basic information to get started.</p>
<input type="text" placeholder="Name" style="width: 100%; padding: 10px; margin: 5px 0; border: 2px solid #e2e8f0; border-radius: 6px;">
<input type="email" placeholder="Email" style="width: 100%; padding: 10px; margin: 5px 0; border: 2px solid #e2e8f0; border-radius: 6px;">
</div>
<div class="step-actions">
<button
class="btn-prev"
popovertarget="step1"
popovertargetaction="hide">
Cancel
</button>
<button class="btn-next"
popovertarget="step1"
popovertargetaction="hide"
onclick="setTimeout(() => document.getElementById('step2').showPopover(), 100)">
Next →
</button>
</div>
</div>
<!-- Step 2 -->
<div id="step2" popover="manual" class="step">
<h3>Step 2: Preferences</h3>
<div class="step-content">
<p>Choose your preferences:</p>
<label><input type="checkbox"> Email notifications</label><br>
<label><input type="checkbox"> Dark mode</label><br>
<label><input type="checkbox"> Weekly digest</label>
</div>
<div class="step-actions">
<button class="btn-prev"
popovertarget="step2"
popovertargetaction="hide"
onclick="setTimeout(() => document.getElementById('step1').showPopover(), 100)">
← Back
</button>
<button class="btn-next"
popovertarget="step2"
popovertargetaction="hide"
onclick="setTimeout(() => document.getElementById('step3').showPopover(), 100)">
Next →
</button>
</div>
</div>
<!-- Step 3 -->
<div id="step3" popover="manual" class="step">
<h3>Step 3: Complete</h3>
<div class="step-content">
<p>✅ Setup complete! You're all set to go.</p>
<p>Click finish to start using the app.</p>
</div>
<div class="step-actions">
<button class="btn-prev"
popovertarget="step3"
popovertargetaction="hide"
onclick="setTimeout(() => document.getElementById('step2').showPopover(), 100)">
← Back
</button>
<button class="btn-finish"
popovertarget="step3"
popovertargetaction="hide"
onclick="alert('Setup complete!')">
Finish
</button>
</div>
</div>
</div>
</body>
</html>
Switches between open and closed states:
< button popovertarget = " menu " > Menu </ button >
< button popovertarget = " menu " popovertargetaction = " toggle " > Menu </ button >
< div id = " menu " popover > Content </ div >
Behavior:
If popover is closed → Opens it
If popover is open → Closes it
Only opens the popover:
< button popovertarget = " menu " popovertargetaction = " show " >
< div id = " menu " popover > Content </ div >
Behavior:
If popover is closed → Opens it
If popover is already open → Does nothing
Use cases:
Open buttons in multi-step workflows
Explicit “show” actions
When you have separate open/close buttons
Only closes the popover:
< button popovertarget = " menu " popovertargetaction = " hide " >
< div id = " menu " popover > Content </ div >
Behavior:
If popover is open → Closes it
If popover is already closed → Does nothing
Use cases:
Close buttons inside popovers
Explicit “dismiss” actions
Cancel buttons in dialogs
<!-- Good: Toggle for simple menus -->
< button popovertarget = " menu " popovertargetaction = " toggle " >
<!-- Good: Separate show/hide for clarity -->
< button popovertarget = " dialog " popovertargetaction = " show " >
<!-- Inside the dialog -->
< button popovertarget = " dialog " popovertargetaction = " hide " >
<!-- Button text matches action -->
< button popovertarget = " menu " popovertargetaction = " show " >
< button popovertarget = " menu " popovertargetaction = " hide " >
<!-- Generic text with toggle -->
< button popovertarget = " menu " popovertargetaction = " toggle " >
<!-- Manual popovers need explicit close -->
< button popovertarget = " this-popover " popovertargetaction = " hide " >
popovertargetaction = " hide "
popovertarget-next = " step2 "
onclick = " document . getElementById ( ' step2 ' ) . showPopover () " >
popovertargetaction = " hide "
onclick = " document . getElementById ( ' step1 ' ) . showPopover () " >
Access the action value via JavaScript:
const button = document . getElementById ( ' myButton ' );
button . setAttribute ( ' popovertargetaction ' , ' show ' );
const action = button . getAttribute ( ' popovertargetaction ' );
console . log ( action ); // "show", "hide", or "toggle"
// Use popoverTargetAction property (Camel case)
button . popoverTargetAction = ' hide ' ;
console . log ( button . popoverTargetAction ); // "hide"
const popover = document . getElementById ( ' my-popover ' );
popover . addEventListener ( ' toggle ' , ( event ) => {
if ( event . newState === ' open ' ) {
console . log ( ' Popover opened ' );
console . log ( ' Popover closed ' );
// Change button text based on state
const toggleBtn = document . getElementById ( ' toggle-btn ' );
popover . addEventListener ( ' toggle ' , ( event ) => {
if ( event . newState === ' open ' ) {
toggleBtn . textContent = ' Close Menu ' ;
toggleBtn . textContent = ' Open Menu ' ;
< button popovertarget = " sidebar " popovertargetaction = " show " >
< div id = " sidebar " popover = " manual " >
< button popovertarget = " sidebar " popovertargetaction = " hide " >
< button id = " menu-toggle " popovertarget = " menu " popovertargetaction = " toggle " >
< span id = " text " > Menu </ span >
document . getElementById ( ' menu ' ) . addEventListener ( ' toggle ' , ( e ) => {
const icon = document . getElementById ( ' icon ' );
const text = document . getElementById ( ' text ' );
if ( e . newState === ' open ' ) {
text . textContent = ' Close ' ;
text . textContent = ' Menu ' ;
Browser Support Chrome 114+ Edge 114+ Safari 17+ Firefox 125+ (behind flag)