Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add switch attribute to the input element to allow for a two-state switch control. #9546

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

lilyspiniolas
Copy link

@lilyspiniolas lilyspiniolas commented Jul 21, 2023

Addresses #4180. This change would add a switch attribute that applies to the input element when it's in the checkbox state. When set, the input would appear as a two-state switch control with an on and off state instead of a checkbox control with an on, off, and indeterminate state. Because switch is an attribute and not a new type, and because submitted data is the same, it maintains a level of backwards compatibility with older browsers and browsers that have not implemented the control since it will still render a checkbox.

Example usage:
<input type="checkbox" switch>

(See WHATWG Working Mode: Changes for more details.)


/acknowledgements.html ( diff )
/custom-elements.html ( diff )
/index.html ( diff )
/indices.html ( diff )
/input.html ( diff )
/rendering.html ( diff )
/semantics-other.html ( diff )

@gregwhitworth
Copy link

@lilyspiniolas looking at the discussion in the issue linked I don't see any resolutions to some of the later discussions around a cohesive design; however I'm unsure where that stands given the statement that Google has given up on standardizing this. Is that still true @mfreed7 @domenic ??

@domenic
Copy link
Member

domenic commented Jul 21, 2023

My team at Google that was working on this in the 2019 era is no longer. @mfreed7 is the point person for related work now, and so is the most relevant person to ask for a Google position.

My personal and HTML-editor opinion is that it would still be nice to use switch as an opportunity to design a new form control element, separate from <input>. It could embody modern best practices, avoid the mistakes of <input> like value="" vs. defaultValue, and avoid HTMLInputElement's everything-everywhere-all-at-once design. But, I can understand how that's more work, and has some drawbacks around progressive enhancement etc. So if we go the <input type=checkbox switch> route, I will be sad at the missed opportunity, but nothing more.

@annevk annevk added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: forms needs tests Moving the issue forward requires someone to write tests labels Jul 21, 2023
Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally seems fine.

Presumably the new input type should have different intrinsic dimensions than a checkbox/radio. If so it'd be good to have them at least informally on the spec so that we can have interoperable implementations?

source Outdated Show resolved Hide resolved
source Outdated
data-x="attr-input-type-checkbox">checkbox</span> state, the <code
data-x="dom-input-indeterminate">indeterminate</code> appearance no longer applies, and its
control becomes a true two-state control with only two visual states which indicate the
element's <span data-x="concept-fe-checked">checkedness</span>.</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this element able to have a different intrinsic size than a checkbox? If so, what size should it be?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@emilio it seems we currently haven't detailed the native and primitive appearances of checkboxes, but I don't think there's opposition to defining this if there's some guidance. Perhaps @zcorpan can help with this?

@mfreed7
Copy link
Contributor

mfreed7 commented Aug 1, 2023

My personal and HTML-editor opinion is that it would still be nice to use switch as an opportunity to design a new form control element, separate from <input>. It could embody modern best practices, avoid the mistakes of <input> like value="" vs. defaultValue, and avoid HTMLInputElement's everything-everywhere-all-at-once design. But, I can understand how that's more work, and has some drawbacks around progressive enhancement etc. So if we go the <input type=checkbox switch> route, I will be sad at the missed opportunity, but nothing more.

+1 to perhaps minting a new element for this, rather than further tangling the <input> element. But I also agree with @domenic that it would be "ok" to do it this way.

Another potential issue is that there are some strong opinions pushing back on the concept of toggle buttons as a UI element. E.g. Toggles suck!

Having said that, my main push back against this PR is that I believe that any new element like this needs to be developer-styleable out of the gate. I think we should be standardizing the parts of the control and allowing for e.g. CSS pseudo elements to style the parts, or sub-elements to replace parts of the control if needed. I would push back against a UA-provided switch that isn't easy to customize.

@smaug----
Copy link

+1 on the styling, as I hinted already 5 years ago in #4180 (comment) :)

@domenic
Copy link
Member

domenic commented Aug 2, 2023

Having said that, my main push back against this PR is that I believe that any new element like this needs to be developer-styleable out of the gate. I think we should be standardizing the parts of the control and allowing for e.g. CSS pseudo elements to style the parts, or sub-elements to replace parts of the control if needed. I would push back against a UA-provided switch that isn't easy to customize.

I think switches (and checkboxes) are simple enough that existing techniques might suffice? In particular: appearance: none + selectors for :checked = style the two states however you like. And I think (but am not sure) that existing CSS animations and transitions are enough to allow custom transitions between the states?

This would be a different story if there were developer-controlled content inside the switch/checkbox, like there is with selectmenu or more complex inputs. But the "customizable UI content" of switch/checkbox seems to me to be, what they look like in their two/three states, and transitions between those states.

@gregwhitworth
Copy link

This would be a different story if there were developer-controlled content inside the switch/checkbox, like there is with selectmenu or more complex inputs. But the "customizable UI content" of switch/checkbox seems to me to be, what they look like in their two/three states, and transitions between those states.

I agree and disagree all at the same time. If we look at any other major application platform (iOS, Android, Windows) they all come with switch and checkbox solutions as separate controls and most of them have more complex content underneath of them. While we "can achieve" a checkbox look how we want I still need to wrap it and then build out my end desired solution when I could, assuming I had access to the parts adjust the border-radius, shadows, etc.

Because of this I'm going to +1 @mfreed7 recommendation of a new element and having them styleable out of the box.

@mfreed7
Copy link
Contributor

mfreed7 commented Aug 2, 2023

I think switches (and checkboxes) are simple enough that existing techniques might suffice? In particular: appearance: none + selectors for :checked = style the two states however you like.

This is what developers (rightfully) complain about though. Sure it’s possible. “Just do appearance:none and then build the entire thing from scratch yourself.” What I’m asking for is the ability to tweak the appearance without having to recreate it from complete scratch. Like, change the border style. Change the “on/off” symbols. Change any colors used. Etc.

@mfreed7
Copy link
Contributor

mfreed7 commented Aug 2, 2023

Would it make sense to bring this issue to OpenUI to discuss it further?

@josepharhar
Copy link
Contributor

Is there a prototype of this implemented in safari that we can test out?

@lilyspiniolas
Copy link
Author

What about two pseudo-elements, one for the "knob" on the switch and one for the "track"? That way there can be more in-depth customizations beyond accent-color, and if web-developers want more control they can still use appearance: none.

@scottaohara
Copy link
Collaborator

is the intent to completely leave styling up to developers to implement - or if it's not in scope for this change, would a future issue/pr to add default user agent styling be on the table for input type=checkbox switch ?

opinionated/rushed CSS aside - https://codepen.io/scottohara/pen/oNQmraB - it's not a lot of work to restyle using the appearance approach - so i personally don't mind one way or the other (the inclusion of pseudo elements specific to switch attribute being added would be very welcome). But, there is at least a number of base level styles that every dev would need to do to create a common design for a switch, which would hopefully not have the knob vanish in Windows high contrast mode (which mine avoids by use of declaring a border, instead of a background to 'fill' the knob).

again, if this is out of scope for this PR / not desired unless an actual <switch> element is created, I'm totally fine with that. just curious what opinions on the matter may be.

@nt1m
Copy link
Member

nt1m commented Aug 4, 2023

Yes, I totally agree that pseudo elements (and possibly basic styling) should be added for the track & the knob.

@gfellerph
Copy link

@domenic and @mfreed7, there is a draft PR for a switch proposal at OpenUI: openui/open-ui#785

Preview: https://deploy-preview-785--open-ui.netlify.app/components/switch.explainer/

In this proposal I tried to address popular features like adding arbitrary content to the thumb or track sides (research page: https://open-ui.org/components/switch/). The proposal therefore suggests adding a <switch> element with some key child elements where authors can easily place this content.

The proposal is still a work in progress. I'd be happy to contribute parts of my proposal to your efforts @lilyspiniolas if this makes any sense or is of any help.

@nt1m
Copy link
Member

nt1m commented Aug 7, 2023

The switch element proposal gives nice insight into what styling could be useful, thanks. Though I think we should stick with re-using input[type=checkbox] so older browsers can get graceful fallback to a checkbox for free without any effort.
For styling, pseudo elements can be added to this proposal. I hope we can get consensus at least on the basic HTML approach before that though.

@gfellerph
Copy link

@nt1m thanks for the feedback. Backwards compatibility would be a nice plus. There are two other aspects that differentiate the switch from a checkbox.

  1. Most analysed design systems specify that a switch can't have an indeterminate state and should toggle a binary option only
  2. Most analysed design systems encourage to take immediate action upon toggling the switch where checkboxes have to be submitted via form in order to take effect (in most cases). In that regard, the switch behaves more like a stateful button.

After doing this research, I wondered if a switch should even be a form control.

@lilyspiniolas
Copy link
Author

@gfellerph The implementation proposed in this PR already addresses your first point; the data submitted by a switch control is binary only, and it does not have an indeterminate visual state nor does it match the indeterminate pseudo-class. As for the second point, while I agree that switches most commonly take immediate action in UIs, it's still not always the case on the web (nor is it for the real-world switches the control is modeled off of).

As such, we still want it to be a form control because right now we want that choice between immediate action and form data to be there, and we want it to be easy for web-developers to implement either way.

@mfreed7
Copy link
Contributor

mfreed7 commented Aug 10, 2023

Fairly late notice, but this is on the agenda for discussion at today’s OpenUI meeting:

https://github.com/openui/open-ui/blob/main/meetings/telecon/2023-08-10.md

@mfreed7
Copy link
Contributor

mfreed7 commented Aug 10, 2023

Fairly late notice, but this is on the agenda for discussion at today’s OpenUI meeting:

https://github.com/openui/open-ui/blob/main/meetings/telecon/2023-08-10.md

Meeting notes: openui/open-ui#338 (comment)

@lukewarlow
Copy link
Member

lukewarlow commented Aug 12, 2023

Just some thoughts from a web developer.

I'm struggling to find any benefit to this switch attribute on top of just using a checkbox? Is it purely default styling? Is that actually all that useful given most designers probably want more than accent-color will provide? Could that not be done with some new appearance: switch CSS?

Edit: Hadn't thought of the accessibility semantics makes sense that this can't just be CSS now.

As others have stated if we could have <switch> which would undo the mistakes of input that'd be nicer imo.

I'm particularly unkeen on the idea this would default to the same value semantics as checkboxes. "on" being the default checked value and no value being submitted when "unchecked" is fairly unintuitive for a checkbox imo.

It would be even less intuitive for a switch. A switch imo always has a value it's true or false (though an indeterminate null state could also be useful), unlike a checkbox where it could be argued that unchecked is an empty state.

Not sure if this is desired but sometimes switches have a default "submit" behaviour too?

Having a basic backward compat "switch" initially and then adding <switch> as something new in future could be okay I guess but would probably be hard to explain to newbies.

@patrickhlauke
Copy link
Member

beyond appearance, this is about how the control is exposed to assistive technologies, and how they then announce it. one of the confusing aspects of "faking" switch controls with just a checkbox and CSS is that for screen reader users, it's still announced as "checkbox, not checked / checkbox, checked", which depending on the label used can be very confusing

@lilyspiniolas
Copy link
Author

Wrote some wpt tests: https://github.com/lilyspiniolas/wpt-switch

@nt1m
Copy link
Member

nt1m commented Dec 21, 2023

@nt1m I see it follows the macOS Differentiate without colours, that's great to see! Tangential but it would be good to try and get support for w3c/csswg-drafts#7406 to allow authors to implement this in any custom designs they're using for this and other control UI.

I agree it would be good to have this, there's probably some thought to be put in the privacy aspect of it though (potentially some opt out to these extra fingerprinting bits in the UI or such, or through Tor-like resistFingerprinting protection).

The screen reader behaviour on some of these is problematic (the CSS content is being announced which is superfluous). I believe the content property supports a second parameter that could solve it content: "Off"/"" but afaik only Chromium supports this. What's the suggested solution to this?

WebKit should probably just implement the alt-text parameter for content cc @cookiecrook. Though I would argue it would be better for authors to use SVG in this case, since these are visual decorations that you'd want to have consistent across platforms, with consistent sizing/style/font. Another solution is to support content on ::track / ::thumb directly and have the UA just aria-hidden the shadow tree containing the pseudos. This seems like a solvable problem in general that I'm not too concerned about atm.

@mfreed7
Copy link
Contributor

mfreed7 commented Dec 21, 2023

@mfreed7 @gregwhitworth @josepharhar The implementation of <input type="checkbox" switch> landed in STP 185. It's enabled by default. However, if you want the ::track & ::thumb pseudos, you need enable the ::thumb and ::track pseudo-elements feature flag separately, here is a demo of what you can do with those:

Looks nice! Congrats. I assume this is just for testing purposes?

Another solution is to support content on ::track / ::thumb directly and have the UA just aria-hidden the shadow tree containing the pseudos.

This seems like maybe the right solution? It feels like that should be part of the initial shipment so blog posts and demos don't crop up with content on the ::before/::after pseudos that gets copy pasted along and causes a11y issues?

@jacobrask
Copy link

jacobrask commented Dec 21, 2023

Should buttons have a similar switch attribute?

Switch toggles are often used to toggle something immediately, unlike a checkbox which requires an additional submit action.

Consider a typical settings view with different switches. Each switch could be a submit button with a different name or formaction to toggle a specific option.

@cookiecrook
Copy link

WebKit should probably implement the alt-text parameter for content

Tracked in WK #159022: WebKit was first to implement the original alt property syntax on generated content (and still does) but hasn't updated to the newer (albeit no longer "new") syntax that settled.

@hober
Copy link
Contributor

hober commented Dec 21, 2023

Another solution is to support content on ::track / ::thumb directly

Yes, please.

@nt1m
Copy link
Member

nt1m commented Dec 22, 2023

Tracked in WK #159022: WebKit was first to implement the original alt property syntax on generated content (and still does) but hasn't updated to the newer (albeit no longer "new") syntax that settled.

I put up a PR to implement this: WebKit/WebKit#22185

Looks nice! Congrats. I assume this is just for testing purposes?

Yep!

@lukewarlow
Copy link
Member

Thanks for the quick turnaround on that!

@jyasskin
Copy link
Member

jyasskin commented Dec 23, 2023

As harm reduction, it probably makes sense to add something like this, but I think the spec needs more detail to ensure implementations actually reduce the harm from overuse of switch elements. For example:

  • Should the 'inline-start' edge be "off" and the 'inline-end' edge be "on"? Or 'left' and 'right'? This is semantic, not just style, because it determines whether <p>Off <input type=checkbox switch> On</p> is correct.
  • Should all implementations default to showing some text inside the control, or is it sufficient for https://www.w3.org/WAI/WCAG21/Understanding/use-of-color.html to allow users to turn on an OS setting that shows the setting in a non-color way?
    • Is there any guidance for what that text should be? Do non-tech users understand that "O" is off and "I" is on?
  • Can HTML say anything about when the semantics of a situation make it appropriate to use a switch instead of a checkbox? Right now, the PR appears to say that a checkbox is for when you want a tristate control, and a switch is for a 2-state control, but I don't think that's the actual criterion.

@MrHBS
Copy link

MrHBS commented Jan 15, 2024

Can we use this attribute on buttons? Switches are toggle buttons after all. I really wish we had a <switch> element instead.

@mfreed7
Copy link
Contributor

mfreed7 commented Jan 26, 2024

Looks nice! Congrats. I assume this is just for testing purposes?

Yep!

Still just for testing purposes? It looks like it's shipping now. Will that go out with the pseudos enabled, or will it not be stylable?

@nt1m
Copy link
Member

nt1m commented Jan 26, 2024

Looks nice! Congrats. I assume this is just for testing purposes?

Yep!

Still just for testing purposes? It looks like it's shipping now. Will that go out with the pseudos enabled, or will it not be stylable?

The initial version won't be styleable, but the main reason we're holding off is so we can ship the pseudo-elements for input[type=range], progress, meter at the same time (see w3c/csswg-drafts#4410). Given they have the same names as the ones used for switch, it makes sense to ship together so @supports selector(::thumb) will correctly reflect support for all of the supported form controls rather than just switch. Other than that, the pseudo-elements are pretty much ready for shipping.

(Also we recently noticed that we didn't exactly implement the names from the CSSWG resolution which were prefixed with ::slider-, see w3c/csswg-drafts#9830)

@scottaohara
Copy link
Collaborator

created a webkit bug today for some unexpected naming from pseudo content that is redundant at best, and awkward/confusing at worst if one is not properly naming (labelling) their switches. w3c/html-aam#510

Related discussion / and pontificating about what could be done about this unwanted behavior in the ARIA wg as well - w3c/aria#2085 (comment)

re: @MrHBS

Can we use this attribute on buttons? Switches are toggle buttons after all. I really wish we had a <switch> element instead.

well, sort of. There is a concept of a toggle button which can be created by use of aria-pressed on a button element, but that is "different" than a switch. Probably a new issue/proposal to file, rather than something this effort should tackle.

@chrishtr
Copy link
Contributor

The Chrome DOM team doesn't think the switch implementation in Safari is ready to ship, but Safari has announced that it's shipping in 17.4. While browsers can always make conscious decisions to ship unilaterally, we should always try to reach consensus first, but we don’t have that yet and I’m not sure it was requested explicitly (and if it was we would have said that it is on a reasonable track but is not yet done). This PR is under active design, and has open questions such as a lack of an interoperable rendering model, or support for customizable styling. There is also an explainer at OpenUI which has useful aspects not already incorporated here.

We also believe it is a mistake to add another un-styleable form control (we don’t think appearance:none is good enough) to the platform, since styleability is a core reason why developers fail to adopt the built-in controls. Work is underway to add styleability to other existing form controls, but doing so without breaking web compat is challenging, and may end up causing pain for web developers during the migration.

Finally, the feature isn't specified well enough to ship. Especially until the track and thumb are customizable, authors need to know and possibly control which side of the element is on vs off. Also, as @scottaohara noticed last week, that semantic difference probably includes labels for the two states, but the design that Safari's shipping doesn't address that aspect and may foreclose the possibility of using nested elements to define those labels. Implementers also need to know how to make the visual appearance accessible.

We also want to emphasize that this comment doesn't reflect negatively on the quality of @lilyspiniolas' proposal, specification, or implementation to date. It's about how to proceed since then.

@annevk
Copy link
Member

annevk commented Mar 12, 2024

Hey @chrishtr, thanks for the feedback! I left a reply at #4180 (comment).

source Show resolved Hide resolved
sideshowbarker added a commit to sideshowbarker/ladybird that referenced this pull request Dec 12, 2024
In conformance with the requirements of the spec PR at
whatwg/html#9546, this change adds support for
the “switch” attribute for type=checkbox “input” elements — which is
shipping in Safari (since Safari 17.4). This change also implements
support for exposing it to AT users with role=switch.
sideshowbarker added a commit to sideshowbarker/ladybird that referenced this pull request Dec 12, 2024
In conformance with the requirements of the spec PR at
whatwg/html#9546, this change adds support for
the “switch” attribute for type=checkbox “input” elements — which is
shipping in Safari (since Safari 17.4). This change also implements
support for exposing it to AT users with role=switch.
sideshowbarker added a commit to sideshowbarker/ladybird that referenced this pull request Dec 12, 2024
In conformance with the requirements of the spec PR at
whatwg/html#9546, this change adds support for
the “switch” attribute for type=checkbox “input” elements — which is
shipping in Safari (since Safari 17.4). This change also implements
support for exposing it to AT users with role=switch.
sideshowbarker added a commit to sideshowbarker/ladybird that referenced this pull request Dec 12, 2024
In conformance with the requirements of the spec PR at
whatwg/html#9546, this change adds support for
the “switch” attribute for type=checkbox “input” elements — which is
shipping in Safari (since Safari 17.4). This change also implements
support for exposing it to AT users with role=switch.
AtkinsSJ pushed a commit to LadybirdBrowser/ladybird that referenced this pull request Dec 13, 2024
In conformance with the requirements of the spec PR at
whatwg/html#9546, this change adds support for
the “switch” attribute for type=checkbox “input” elements — which is
shipping in Safari (since Safari 17.4). This change also implements
support for exposing it to AT users with role=switch.
@sideshowbarker
Copy link
Contributor

I’ve implemented the switch control in Ladybird LadybirdBrowser/ladybird@583ca6af89c.

There’s room for improvement in the implementation around the restyleability of the control — and it doesn’t even attempt to handle restyling of the track and thumb — but it’s enough for Ladybird users/contributors to try out and give feedback on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: forms
Development

Successfully merging this pull request may close these issues.