v135 · dom

Invoker Commands; the command and commandfor attributes

Adding command and commandfor attributes to <button> elements would allow authors to assign behaviour to buttons in a more accessible and declarative way, while reducing bugs and simplifying the amount of JavaScript pages are required to ship for interactivity. Buttons with commandfor and command attributes will - when clicked, touched, or enacted via keypre

concepts

  1. command + commandfor, no JS

    Pick a built-in command (show-modal, toggle-popover, close) from the menu and watch a real button drive a <dialog> or [popover] target without a single event listener.

  2. Custom buttons open native pickers

    The explainer's secondary use case: command="show-picker" lets your own branded button trigger the native date / colour / file / month picker on any <input>.

  3. Custom command protocol

    Beyond the built-ins, custom commands use a -- prefix. A mini audio-player remote dispatches --play, --pause, --seek via commandfor, and the target listens via the command event — no click handlers.

  4. Event delegation bench

    Side-by-side: 16 buttons firing on a parent container under both the new command event and the classic click + closest() dance. See how delegation reads event.command and event.source with zero per-button bookkeeping.

  5. Settings panel

    An app toolbar with four buttons — Account, Preferences, Share, and Help — each wired to a different <dialog> or [popover] target via commandfor and command. Not a single click listener on any button. The close buttons inside each panel also use command="close".

why it shipped

All elements within the DOM are capable of having interactions added to them. A long while ago this took the form of adding inline JavaScript to an event attribute, such as <button onclick="other.open()"></button>. Inline JavaScript has (rightly so) fallen out of favour due to the security and maintainability concerns. Newer pages may instead introduce more JavaScript to imperatively discover elements and call addEventListener('click', ...) to invoke the same behaviour. These patterns reduce developer experience and introduce more boilerplate and friction, while remediating security and mainta

references