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.
<triggerbikeshed type>
.<button type>
not submitThis is aimed to resolve
<dialog>
elements without JavaScript by @keithamustoggle
, which will not be a form participant.<button>
, for
like that of <label>
, as an IDREF for the target element.togglable
which marks an element as toggable by <button type="toggle">
.<dialog>
) with togglable
attribute gets show/hide by a hidden
attribute toggle. This allows for developers to potentially override the styling with CSS for responsive design.ToggleEvent
is dispatched.<button type="toggle" for="togglableid">Toggle</button>
<!-- calls `dialog.showModal() -->
<dialog id="togglableid"></dialog>
Accessibility: Nothing happens as focus change is enough.
<!-- 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:
aria-details
on <button type="toggle">
when the toggle button is not the next immediate accessibility sibling of the togglable element in the accessibility tree. See popover
implicit details relation mappings.aria-expanded
<!-- 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 { ... }
toggle
the name is used here as having partity with how ToggleEvent
is used in the HTML spec.
Fired at details elements when they open or close; fired on elements with the popover attribute when they are transitioning between showing and hidden”
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.
This is largely borrowed from Toggle Button Proposal by @lukewarlo
press
, which will not be a form participant.<button>
, for
like that of <label>
, as an IDREF for the target element (if applicable).<button>
, command
to specify a short list of commands that can be exposed to the developers, like toggling media states like play|pause
, mute|unmute
, etc.defaultPressed
which marks the toggle button’s default pressed state to “true
”.defaultMixed
which marks the toggle button’s default pressed state to “mixed
”.<state>
with attributes on|off
so the browser can switch them according to the targeted element’s command state.Given
<video id="videoid"></video>
<button type="press" for="videoid" command="mute" defaultPressed>Mute</button>
Accessibility:
aria-pressed
.<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:
aria-pressed
to mixed
.aria-pressed
` when pressed.<button type="press" defaultMixed>
<state on>Bold</state> <!-- show -->
<state off>Unbold</state>
<state mixed>?</state> <!-- TBD if needed -->
</button>
Accessibility:
<state>
element can potentially be used with toggle button as well, in which case a NAMECHANGE event will be dispatched, instead of toggling aria-pressed
state.[!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.
<cyclebikeshed>
that is to have similar user agent style as <button>
.<cyclebikeshed>
<option value="happy"></option>
<option value="neutral"></option>
<option value="sad"></option>
</cyclebikeshed>
Accessibility:
cycle
.<button type="cycle">
<option>happy</option>
<option>neutral</option>
<option>sad</option>
</button>
Accessibility:
[!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.
CommandEvent
named ‘custom-behavior’ on targeted element.<button type="button" for="custom" command="custom-behavior">Surprise!</button>