Skip to content

scottaohara/std-switch

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A standard 'Switch' form control

Authors

Introduction

This document proposes a new HTML element for a 'switch' control. It is provided as a built-in module.

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 switch ARIA role.
  • It's hard to change checkbox's appearance to a switch-like appearance, for when that user experience is desired.

Goals

  • Identical appearance on all platforms and all supported browsers by default
  • 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

Sample code

<script type="module">
import 'std:elements/switch';
</script>

<form action="...">
  <label>Enable something <std-switch name="something"></std-switch></label>
  <input type="submit">
</form>

This shows something like:
Sample image

Users can turn on/off the switch by clicking it, and submitting the form will have an entry for the switch control.

Demo page

Proposed API

The element is provided as a built-in module. import 'std:elements/switch' defines <std-switch> element and StdSwitchElement interface.

<std-switch> is similar to <input type=checkbox> in terms of API. A <std-switch> instance has two states; "off" and "on". It doesn't support indeterminate state like the checkbox.

Content attributes:

TODO: Supports autofocus, which should be a global attribute. (whatwg/html#4563)

These attributes should work same as existing form controls.

<std-switch> should support checked and defaultchecked attributes (Issue #2). There are some approaches for them. We have not decided yet. (Issue #4)

  • A) Compatible with <input type=checkbox>
    checked attribute represents the default state, and defaultChecked property reflects on checked attribute. No attribute mapped to checked property.
  • B) Simple mappings
    defaultChecked property reflects on defaultchecked attribute value, and checked property reflects on checked attribute. Code like switch.checked = true adds checked attribute. We need to specify defaultchecked attribute if we want to reset the element to on state, like <std-switch defaultchecked checked>

Properties and functions

  • checked - Represents the element's state. See the previous section

  • defaultChecked - 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

  • type - returns 'std-switch'

  • 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

Pseudo classes

  • Global ones such as :focus :hover :target
  • :valid - match if the element has no required attribute, of if the element has required attribute and the state is on.
  • :invalid - match if the element doesn't match to :valid.
  • :disabled - match if the element has disabled attribute, or an ancestor <fieldset> has disabled attribute.
  • :enabled - match if the element doesn't match to :disabled.

TODO: Supports :checked (Issue #3), :required, and :optional (w3c/webcomponents#813)

Events

<std-switch> dispatches input and change events when a user changes the element's state.

Relationship with other elements

  • form
    Markup like <form>...<std-switch></std-switch>...</form> associates the <std-switch> element to the <form>. <form>'s elements property lists the <std-switch>, and submitting the <form> adds an entry for the <std-switch>.
  • fieldset
    Markup like <fieldset>...<std-switch></std-switch>...</fieldset> associates the <std-switch> element to the <fieldset>. <fieldset>'s elements property lists the <std-switch>, and disabling the <fieldset> also disables the <std-switch> implicitly.
  • label
    Markup like <label>...<std-switch></std-switch></label> associates the <std-switch> element to the <label>. Clicking anywhere in the <label> changes the state of the <std-switch>.

Form submission

There are two approaches. We have not decided yet. (Issue #5)

  • A) Compatible with <input type=checkbox>
    <std-swtich name=something> with "off" state will send no entry. One with "on" state will send value attribute value if it exists, or something=on.
  • B) Send state simply
    <std-swtich name=something> with "off" state will send something=off, one with "on" state will send something=on.

Appearance customization

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.

TODO: Full customization. Shadow parts? CSS custom properties? (Issue #7)

Considered alternatives

Making <input type=chekbox> customizable

Providing a swtich control as a variant of <input type=checkbox> would be possible. We can add switch content attribute, add swtich keyword to appearance CSS property, or something.

However, as decribed in 'Why a switch control?' section, using <input type=checkbox> 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.

Native implementation in UAs vs. a built-in module

Form control elements are major sources of interoperability issues. Native implementations likely introduce new interoperability issues.

UAs can share a built-in module implementation because it's a JavaScript code, and web developers won't see interoperablity issues with it at all.

Third-party library, vs. a built-in module

See JavaScript Standard Library Proposal

References & Acknowledgments

  • whatwg/html#4180 posted by Atishay Jain gave us a motivation to start this project.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 82.4%
  • HTML 17.6%