A standard 'Switch' form control
- Kent Tamura email@example.com
This document proposes a new HTML element for a 'switch' control. It is provided as a built-in module.
This proposal is intended to incubate in the WICG once it gets interest on its Discourse thread. After incubation, if it gains multi-implementer interest, it will graduate to the HTML Standard as a new standard HTML element.
Why a switch control?
Many UI frameworks have switch controls to represent off/on states and ask a user to change the state. As of April 2019 the HTML standard has a checkbox, which is functionally similar to switch control. However:
- Semantically, a switch and checkbox have different meanings, with a switch being more appropriate for turning things on/off. (See e.g. Microsoft Fluent design guidelines, Nielsen Norman Group, UX Planet.)
- Switches and checkboxes manifest differently to accessibility technology: see the
- It's hard to change checkbox's appearance to a switch-like appearance, for when that user experience is desired.
- Identical appearance on all platforms and all supported browsers by default (Issue #21)
- Easy and flexible customization
- The switch control should provide a way to switch its appearance from the default one to platform-dependent one.
- The switch control should provide a way to customize color, size, radius, etc. of its visual parts.
- API similar to existing form controls
- Explore new ways of building HTML elements, including:
<script type="module"> import 'std:elements/switch'; </script> <form action="..."> <label>Enable something <std-switch name="something"></std-switch></label> <input type="submit"> </form>
Users can turn on/off the switch by clicking it, and submitting the form will have an entry for the switch control.
The element is provided as a built-in module.
import 'std:elements/switch' defines
and it can expose
- Global attributes
autofocus, which should be a global attribute. (whatwg/html#4563)
These attributes should work same as existing form controls.
<std-switch> should support
defaulton attributes (Issue #2).
defaultOn property reflects on
defaulton attribute value, and
on property reflects on
switch.on = true adds
on attribute. We need to specify
if we want to reset the element to on state, like ``` (Issue #4)
Properties and functions
on- Represents the element's state. See the previous section
defaultOn- Represents the default state. See the previous section
disabled- Same as existing form controls
form- Same as existing form controls
labels- Same as existing form controls
name- Same as existing form controls
willValidate- Same as existing form controls
validationMessage- Same as existing form controls
checkValidity()- Same as existing form controls
reportValidity()- Same as existing form controls
setCustomValidity(errorMessage)- Same as existing form controls
- Global ones such as
:valid- match if the element has no
requiredattribute, of if the element has
requiredattribute and the state is on.
:invalid- match if the element doesn't match to
:disabled- match if the element has
disabledattribute, or an ancestor
:enabled- match if the element doesn't match to
change events when a user changes the element's state.
Relationship with other elements
<std-switch>element to the
elementsproperty lists the
<std-switch>, and submitting the
<form>adds an entry for the
<std-switch>element to the
elementsproperty lists the
<std-switch>, and disabling the
<fieldset>also disables the
<std-switch>element to the
<label>. Clicking anywhere in the
<label>changes the state of the
- A) Compatible with
<std-switch name=something>with "off" state will send no entry. One with "on" state will send
valueattribute value if it exists, or
- B) Send state simply
<std-switch name=something>with "off" state will send
something=off, one with "on" state will send
TODO: an easy flag to enable platform-dependent appearance (Issue #6)
When the flag is enabled,
std-switch element is styled as UISwitch on iOS, Material Design switch on Android, Fluent design toggle switch on Windows.
The element provides full customization capability by CSS Shadow Parts.
<std-switch> contains three parts,
thumb are siblings, and
track-fill is a child of
(See Issue #7)
Security and Privacy Considerations
There are no known security or privacy impacts of this feature. Security/privacy impact of this feature is same as
If the platform-dependent appearance is enabled, the origin can detect user's platform. However, that information is already exposed by
<input type=checkbox> customizable
Providing a switch control as a variant of
<input type=checkbox> would be possible.
We can add
switch content attribute, add
switch keyword to
appearance CSS property, or something.
However, as decribed in the 'Why a switch control?' section, using
for a switch control is semantically incorrect.
Also, it would add complexity to UA implementations, and it's difficult to provide
customization flexibility with a switch control implemented by these ways.
As a new global element (instead of a built-in module)
We would like to experiment with ways of making new HTML elements "pay for what you use".
Instead of every page paying the cost of loading a switch implementation into memory as a global (e.g.
we want pages to opt in to using the switch control.
which is also used by other APIs that share the same goals (such as KV Storage).
Note that although adding a global switch control implementation is a small step, it contributes to a tragedy of the commons, which makes it harder and harder to add new APIs and elements. Exploring an opt-in solution here opens the door to more sustainable growth overall.
Leaving this up to libraries
It is possible to continue requiring that web developers use a library to implement switches.
We believe that the platform should instead provide a basic control such as a switch out of the box.
Major modern UI platforms (e.g. Android, iOS, Windows, macOS) all provide switch controls,
and the web should as well.
The story for macOS is "use
NSSwitch and you get a switch control."
The story for the web should be similarly simple, instead of "use a checkbox, customize it with tons of CSS, and remember to change its ARIA
Why does the name have a dash in it?
<std-switch> is unusual compared to built-in HTML elements,
none of which have a dash.
A more natural choice might be
<switch>, or perhaps
The reason to include a dash in the name is to allow the element to be polyfillable, using custom elements. We'd like to experiment with moving away from the world where browsers get a special namespace that can never be polyfilled.
There are alternative ways of achieving this goal; for example, we could lift the dash restriction on custom element names. There is some more discussion in WICG/virtual-scroller#161. This is definitely subject to change as we continue to prototype.
Is this a custom element?
This is a proposal for a new built-in HTML element,
similar to other new-ish elements like
<dialog>, or the proposed
If it graduates from incubation successfully, it will become part of the HTML Standard.
The name does have a dash, as noted above.
And the goal of allowing custom elements to perfectly polyfill
<std-switch> will mean that
<std-switch> behaves like a custom element in many ways.
(As we proceed to writing a rigorous spec, those will be enumerated in detail.)
Indeed, browsers may even choose to implement
<std-switch> using custom elements under the hood.
(Chromium plans to do so.)
But in the end, this is a new element intended for the HTML Standard,
meant to ship natively with browsers.
Will all browsers share code for the switch control?
This is a decision for individual browser vendors to make.
Note that historically some parts of browser codebases are shared
(e.g. Web Audio,
RegExp engines, Web RTC)
while many parts are implemented independently.
It will likely be easier to share code for
<std-switch> than for
because our goal of making it 100% polyfillable and layered means that it will depend on standardized web-exposed API concepts instead of hooking directly into internal implementation details.
But in the end,
this repository will only provide a specification,
which can be implemented however makes most sense to individual browsers.
References & Acknowledgements
- whatwg/html#4180 posted by Atishay Jain gave us a motivation to start this project.