Layout Beginner

Modal controls without onclick handlers

Opening a dialog modally required onclick handlers calling showModal(). Invoker Commands let buttons perform actions on other elements declaratively with commandfor and command attributes.

Old 8 lines
1<!-- Inline onclick or JS event listener -->
2<button onclick="
3  document.querySelector('#dlg')
4  .showModal()">
5  Open Dialog
6</button>
7
8<dialog id="dlg">...</dialog>
Modern
6 lines
1<button commandfor="dlg"
2  command="show-modal">
3  Open Dialog
4</button>
5
6<dialog id="dlg">...</dialog>
buttons control the dialog with no JS

Invoker Commands

This dialog was opened with commandfor and command="show-modal". Zero JavaScript.

commandfor + command="show-modal"

Declarative

Link a button to its target with commandfor (like the for attribute on labels). No querySelector, no addEventListener.

Multiple commands

show-modal, close, show-popover, hide-popover, toggle-popover. One pattern for all interactive elements.

Custom commands too

Prefix with -- for custom commands handled by the command event. Extensible without frameworks.

Browser Support
72%
Chrome Edge Firefox 🔜 Safari 🔜
View on caniuse.com →
Lines Saved
8 → 6
Zero JavaScript
Old Approach
onclick handlers
Inline JS or addEventListener
Modern Approach
Invoker Commands
commandfor + command

How it works

To open a <dialog> modally, you needed JavaScript: either an inline onclick that calls showModal(), or an addEventListener in a script. Same for popovers and closing. Every interactive trigger required its own JS wiring.

Invoker Commands (Chrome 135+) add two HTML attributes: commandfor takes the ID of the target element, and command specifies the action. Built-in commands mirror their JS counterparts: show-modal, close, show-popover, hide-popover, toggle-popover. Custom commands prefixed with -- fire a command event on the target for extensibility.

ESC