Proposals

Toggle button

This proposal leans heavily on new <button type>, which can result in un-supported browsers erroneously submitting a form.

The following solutions are considered and are open for discussions.

  1. Rely on user polyfill to prevent submission.
  2. Create new button-like elements, for example <triggerbikeshed type>.
  3. Investigate making the invalid state of <button type> not submit

This is aimed to resolve

Summary

Demo

Toggle button demo.

Code example

Button

<button type="toggle" for="togglableid">Toggle</button>

Targeted elements

<!-- calls `dialog.showModal() -->
<dialog id="togglableid"></dialog>

Accessibility: Nothing happens as focus change is enough.

Non-modal

<!-- calls `dialog.show() -->
<dialog id="togglableid" togglable></dialog>

<!-- calls `popover.togglePopover() -->
<div id="togglableid" popover>...</div>

<!-- sets `el.hidden = true/false -->
<div id="togglableid" togglable>...</div>

Accessibility:

<!-- SHOULD NOT HAVE implicit aria-details -->
<button type="toggle" for="togglableid">Toggle</button>
<div id="togglableid" togglable>...</div>
<div id="togglableid" togglable>...</div>
<!-- SHOULD HAVE aria-details because the toggable element is the _previous_ sibling to the toggle button -->
<button type="toggle" for="togglableid">Toggle</button>
<!-- SHOULD HAVE implicit aria-details -->
<button type="toggle" for="togglableid">Toggle</button>
<other_elements_important_to_accessibility>
  ...
</other_elements_important_to_accessibility>
<div id="togglableid" togglable>...</div>
<!-- SHOULD NOT HAVE implicit aria-details -->
<button type="toggle" for="togglableid">Toggle</button>
<div> <!-- generic, thus ignored in a11y tree -->
  <article role=none> <!-- role=none ignored in a11y tree -->
    <article aria-hidden=true></article> <!-- hidden/ignored in a11y tree -->
    <article hidden>...</article> <!-- hidden/ignored in a11y tree -->
    <div id="togglableid" togglable>...</div>
      <!-- while there are many elements intervening between this toggable elemetn and its toggle button,
           none of those elements are represented in the a11y tree, and thus as far as the a11y tree is
           concerend, the button and this toggable element are immediate a11y siblings -->
    ...

CSS:

button[type=toggle]:expanded { ... }
button[type=toggle]:collapsed { ... }

Notes






The following proposals are only included for parity to the Invoker proposal from Open UI. They are not being advocated as part of this proposal. Although it may seem like the similar attributes can solve all of these at once, for the reason stated in the WHATWG/HTML issue, I think they should instead each be evaluated from first principal to see what an ideal solution for them is.


Press button

This is largely borrowed from Toggle Button Proposal by @lukewarlo

Summary

Code example

Button

Given

<video id="videoid"></video>
<button type="press" for="videoid" command="mute" defaultPressed>Mute</button>

Accessibility:

<button type="press" for="videoid" command="toggleMute">
  <state on>Mute</state> <!-- show -->
  <state off>Unmute</state> <!-- hidden (consider strong UA hiding so cannoot be easily undone by authors with errant CSS) -->
</button>

Accessibility:

<button type="press" defaultMixed>Bold</button>
<!-- use case, a selection of text is made in a rich text editor.
     only some of the selected text is bold, thus the state of the button should reflect this -->

Accessibility:

<button type="press" defaultMixed>
  <state on>Bold</state> <!-- show -->
  <state off>Unbold</state>
  <state mixed>?</state> <!-- TBD if needed -->
</button>

Accessibility:

Notes

Cycle buttons

[!WARNING]
Incomplete. This is included as it conceptually overlaps with the press/toggle above. It is unclear if this provides a good user experience as the list of options to cycle through is not directly accessible to users without having to first engage with the control, and memorize the available options that do not represent the currently chosen option.

See Toggle/cycle buttons by @annevk.

Form participant option

Summary

Code example

<cyclebikeshed>
  <option value="happy"></option>
  <option value="neutral"></option>
  <option value="sad"></option>
</cyclebikeshed>

Accessibility:

Non-form participant option

Summary

Code example

<button type="cycle">
  <option>happy</option>
  <option>neutral</option>
  <option>sad</option>
</button>

Accessibility:


Declarative custom event

[!CAUTION]
This is included only as an alternative for OPEN UI: invoker/custom behavior. Since it has no specific accessibility benefit, semantic meaning, or conceptual overlaps with the above proposals, should be evaluated separately.

<button type="button" for="custom" command="custom-behavior">Surprise!</button>