Open atishay opened 6 years ago
Shouldn't this be a checkbox with a different style? E.g., appearance: switch
?
cc @whatwg/rendering
Definitely makes more sense as we get backwards compatibility.
Apologies for not welcoming you by the way, I missed this is your first issue. Belatedly, welcome! https://whatwg.org/working-mode#changes and https://whatwg.org/faq#adding-new-features provide some context for the way work is done. I think for this particular request there is enough to go on as this is clearly an established UI widget that makes sense to expose the web in some form. Thanks for raising it.
Indeed, welcome. I'm glad @annevk pointed you to the adding new features FAQ, as it helps keep specific solutions (e.g. <input type="switch">
) separate from the problem statement ("displaying a control that looks like a switch").
Coincidentally we have been having some discussions internally in Chrome about better built-in UI widgets and form controls. At this point I don't have much to report beyond tentative interest in the general program. But there's a lot to still figure out in the specifics: e.g. theme-ability, whether we can do this in a layered way that does not require more browser magic (like appearance
does), etc.
👍 It also seems worth mentioning that ARIA (since ~1.1 I think) now has a switch
role:
I am happy to work with the team if any help in needed in getting this spec'ed or implemented, in whatever form it makes sense to get a toggle switch control into the browsers. I will be careful about not having a solution but only a problem in the future. Really glad to see how active the HTML WG is on their github channel.
@sideshowbarker that's very interesting, that almost suggests there is some semantic related to the presentation of a switch checkbox. Using a CSS property at that point wouldn't work well as that couldn't map to ARIA cleanly.
cc @whatwg/a11y
The ARIA 'switch' role maps to the accessibility APIs, so an element with 'role="switch"' has semantic meaning to screen readers.
I don't think this is a bad idea, but proposals for new browser features can take a long time between conception and implementation across platforms—assuming universal adoption is ever achieved.
Because of this, the question that immediately springs to mind for me is "what does a reliable non-JavaScript fallback pattern look like for this?", and appearance: switch;
in combination with <input type="checkbox">
seems to provide a foundation for a progressively enhanced and accessible switch element.
I agree that's a good consideration, but note that <input type=checkbox switch>
would provide that too and is probably more apt given the slight semantic implication.
Good point @annevk. I can't see any reason why that wouldn't work as well!
There seems to be no progress on this issue for some time. Is there any way I can help?
@tkent-google @cdumez @hober @smaug---- is this something you'd implement if specified?
@atishay apart from getting the above question addressed (implementation interest), we'll need someone to make the relevant changes to the standard and write tests. I suspect a new boolean attribute named switch
is the way to go, signaling a change in presentation. One thing that we'll need to work out is how checkbox's intermediate state works together with this. Presumably we'd disable that somehow.
Sounds reasonable.
When spec'ing this, need to be very careful with styling related properties. We've so often failed to spec those early enough with form control elements. (one option is that there isn't any specific pseudoclasses/elements for switch, but if that is the case, better to spec it)
Why we'd disable the intermediate state? I'd rather try to keep the behavior on JS side as close to checkbox as possible.
Chrome would prefer to not perform a new quick-fix for this, e.g. adding an attribute. We'd instead prefer to work on it more holistically as part of a general question of how to add new form controls and behaviors, in a way that does not involve magic that only browsers could do today (such as adding a new attribute to <input>
and wiring that up to appropriate a11y and styling interactions). This is a longer-term project, but it's one of our priorities for 2019.
(Side note: as a benefit, our preferred approach should entirely determine the styling interactions, helping with @smaug----'s concern.)
More concretely, we'd prefer to see something implemented in JavaScript/custom elements/Houdini/AOM/ElementInternals/etc., and then put into the spec in a way that is indistinguishable from such a solution. If that's not possible today (e.g. due to missing foundational pieces) then we'd like to delay committing to a solution in the spec. Our suspicion is that this will not be possible today, but for those interested in making progress, Chrome's preferred avenue would be to attempt to do so with today's technologies, and see where the gaps are, exactly.
All that said, I would not count this as "strong opposition", so if there are multiple other independent engines who want to add form controls in the usual magic-using way, that would be fine to land as part of the WHATWG progress. Chrome just would not prioritize following such an implementation, as we'd rather commit those resources to working through the general problem space of allowing the set of form controls to be extensible/themeable/polyfillable/etc.
I looked at the various ways to create custom element to do this task. Here are some issues that we would face with Custom Elements:
<input>
tag. <label for="">
. We will have to synchronize values on click and name properties.::before
and ::after
pseudo elements, which in chrome can be placed above the checkbox UI to look like a switch. These properties are not protected by the shadow DOM and modifying the CSSOM from JS is one way that could be done, though it is not very clean.The documentation is scant on custom elements and I am not sure if I missed anything. If needed I can provide a Codepen for approach 2 or 3.
@domenic A form element to have a shadow DOM would be required for a clean implementation. It could associate the value
property and the <label for="id">
and then rest of the details could be filled in by the shadow dom.
Another way, this could be spec'ed out is to allow Shadow DOM to <input>
tag. When a HTMLInputElement is provided a shadow DOM, it could potentially convert to an empty element with no default UI. If a text field is needed, that could be added in shadow DOM and the corresponding properties synchronized. That would allow maximum flexibility with full backwards compatibility. That approach can be taken to provide shadow DOM to any HTML tag and allow extensibility.
@atishay We're standardizing "Form-associated custom elements", and Chrome Canary has it behind a flag. Please refer to https://github.com/w3c/webcomponents/issues/187#issuecomment-444817775
Thanks very much for the exploration, @atishay! Indeed, as @tkent-google mentions, the form-associated custom elements feature would be a crucial building block for this sort of work, I think. We'd love for you to try it out and see how well a switch control built on that works out.
Another approach worth considering is using CSS custom paint (customizing an <input type="checkbox">
), instead of shadow DOM. Although that doesn't help with the accessibility differences mentioned.
I have a basic version of switch using custom elements here: https://codepen.io/atishayjain/pen/XoEQXN?editors=1010
This is not very customizable and I can make a version which is much more dynamic if that helps in standardization. This is not backwards compatible with checkbox.
If needed, I can try the custom paint approach, which could behave like appearance
.
Is there something else that can be done to get some progress in getting a toggle switch element?
@domenic Do we need anything else? Is there still interest in building something in this area?
Google is going to propose standardizing the switch form control as a JavaScript Standard Library. Here is an initial explainer: https://github.com/tkent-google/std-switch/blob/master/README.md
@tkent-google That's pretty cool thanks for sharing. I agree with @domenic statement here. As such, I think we should take this a bit further in a few different ways as I think there a few key pillars to the problems that web developers face with regard to the native controls on the web, some of which you have issues open for so I'll focus those discussions on those.
One thing that I believe we should allow is for built in components to not require the dash. So in this case, we wouldn't have <std-switch>
but simply <switch>
. This would align with our other controls and allow at a quick glance which ones are native and which come from third party code.
Additionally, while I think this can be done in a stepping stone fashion, I don't think the author should be required to import
the control to utilize it, especially since it will already be shipping with the browser. That seems like un-necessary overhead for the author.
The dash question is an interesting one. We've briefly discussed it in another context at https://github.com/WICG/virtual-scroller/issues/161. Maybe we should open an overall issue.
Similarly, we're very interested in exploring a future built on Apple's JavaScript standard library proposal where new high-level features can be opt-in imported, instead of every page paying for every new web platform feature we add forever.
As noted in that issue, the two design choices are connected and synergize with each other.
I opened a WICG thread for this. https://discourse.wicg.io/t/proposal-a-toggle-switch-control-element/3620
Hmmm... an input of type “checkbox” is specified to submit a value of “on” already. That seems like a switch to me. A checkbox is — literally — a toggle control. If ARIA finds a difference worth mentioning then sure, use a role of “switch”, but there should be no need to introduce a whole honking input type for this. Browser vendors need to focus instead on standardizing some style-able parts (like Shadow DOM parts or whatever) to make more visual designs possible, not just for checkboxes but for other input types as well.
@tuespetre Switch is a standard control in most operating systems and native UI toolkits. If the browsers don't have controls natively, we ask the developers to keep reinventing the wheel.
I can use the same logic for checkboxes and say that we already have input type text(or radio) and they should be removed as you can write code to make another input look and behave like a checkbox. The entire DOM could be implemented on a canvas.
I don't disagree with having extensibility in the browser controls and with those we can get the ability to experiment. But asking every web developer to manually build a UI element that native developers get for free does seems a of work.
@atishay well I gotta say now you have me thinking about the physical action that comes with a switch. That is a pretty important experience with visual, audio, and possibly tactile feedback, so I think that you are right, authors and application developers should not have to bear the burden of properly crafting it.
Yall, I was looking at my 3-way bulb lamp tonight. And an input of type “switch” would be excellent if it had the ability to cycle through states.
I created a proof of concept (chromium-based browsers only) for styling of checkbox inputs with a 'toggle' attribute. My preference leans towards 'toggle' naming instead of 'switch'.
https://codepen.io/alystair/pen/jOWWqwa?editors=1100
indeterminate
.Since it's an alternative styling to 'checkbox', implementation wouldn't be as difficult as creating an entirely new input type.
One gotcha I see with plain toggles (such as this POC) is that current state isn't as obvious compared to checkboxes. This may be due to lack of iconography (checkmark, etc). Perhaps allowing for on/off state styling, as seen in many light/dark mode toggles popping up these days may solve the issue.
Have there been any recent developments on the topic of this discussion? Accessibility/assistive technology support for a switch role is inconsistent across browsers and screen readers, in large part due to the different approaches used by developers (start with a checkbox or start with a button). A switch is considered different enough from a checkbox so that it has its own dedicated role in the ARIA specification. The easiest way to standardize support and push for more consistency would be to make a switch a native HTML control, not to mention avoiding the myriad of implementation approaches.
If it would be standardised: Please do not make the behaviour like "type=checkbox" in case it is "unchecked". https://github.com/openui/open-ui/issues/313
FYI. Google gave up standardizing this.
@Wildebrew there have been discussions in a general sense and it has re-surfaced while working on some research into improving the native checkbox. I filed an issue on Open UI here.
Accessibility/assistive technology support for a switch role is inconsistent across browsers and screen readers, in large part due to the different approaches used by developers (start with a checkbox or start with a button).
It would be great if you could share examples or the end user implications of the way in which they've been created. Any concrete impact helps solidify the need vs it being a restyle of a checkbox.
There is now a concrete proposal for this over at #9546. It's essentially an enhanced checkbox and matches most of its semantics, apart from not having an (observed) indeterminate state.
We did consider https://github.com/openui/open-ui/issues/313 and decided that addressing that would best be done independently with the solution being useful for checkboxes as well.
And for a11y it will indeed need to be exposed as role=switch
. I will file an issue for that.
Does it still seem reasonable @smaug----?
As I understand it, both checkbox and button could be valid ways to implement a switch control. This proposal seems specific to checkboxes, do you envision there would be something similar for buttons (where aria-pressed
also comes into play)? I'm thinking a switch
attribute (consistent with this proposal) or type=switch (consistent as there are other types).
One reason for me to use a button on a dark/light mode switch I made (fwiw) is that it is (more) trivial to style.
None of the buttons in HTML have a two-state semantic. It seems that would require quite a bit more changes as you'd have to invent that, add new pseudo-classes, etc. The idea is that with appearance:none
developers should have full control over the styling of a switch, just like they do with checkboxes today. If more affordances are needed though we are definitely interested in hearing about that as ultimately we want all controls to be fully style-able.
Fair enough, agreed appearance: none
is fine as it provides full control.
This was just discussed at OpenUI: https://github.com/openui/open-ui/issues/338#issuecomment-1673745778
I wanted to provide an update here on our current thinking with regards to this control and in particular styling as that's been the sole topic of discussion in the PR (if there's anything else now would be a good time to identify that):
appearance:auto
: this is largely up to the user agent, including the intrinsic dimensions. We desire different intrinsic dimensions for the iOS family of platforms and macOS for instance, and they might also be influenced due to the font size. For the iOS family of platforms the intrinsic dimensions we have in mind are a width of 51 CSS pixels, a height of 31 CSS pixels, and an aspect ratio derived from that. For macOS there's multiple supported intrinsic dimensions, but the default is 32 by 18 CSS pixels. (We might add a small margin as well.)
appearance:none
: the aim here will be that all properties will have their initial values. Our current implementation deviates from this for display
, but we'll address that.
appearance:base
: as this requires a larger discussion and a consistent story across all form controls, we don't consider this to be blocking adding this control.
Pseudo-elements: in principle we have support for ::thumb
and ::track
as sibling child pseudo-elements of the input
element, consistent with the CSS WG resolution on https://github.com/w3c/csswg-drafts/issues/4410. They are not enabled by default for now. An idea we have here is that these will get appearance:inherit !important
so that you cannot get partial "auto" controls. Otherwise the styling should match that of the input
element.
I've reviewed the current PR and the majority looks good to me. But the one key chunk is this one:
<p class="XXX">Need to detail the expected <span>native appearance</span> and <span>primitive appearance</span>.</p>
which needs to be fleshed out. From my point of view, the plan above sounds reasonable, with one exception: appearance:base
. The issue is that this will introduce yet another control to the platform that is either a) non-interoperable (for appearance:auto
) or b) must be reconstructed entirely from scratch (for appearance:none
). There really needs to be option c) an interoperable, stylable switch component that can be "tweaked" without having to reconstruct it entirely. For example: just change the border width on the thumb, without having to provide all of the other colors and borders and sizes.
I would think that for the proposed switch control, the standardized CSS rules implied by appearance:base
would be relatively straightforward - wouldn't they? Might it be possible to include that now, as a way to prove the value of appearance:base
?
How would we enable it in a way such that we don't claim support for appearance:base
for other controls?
How would we enable it in a way such that we don't claim support for
appearance:base
for other controls?
Hmm, yeah, you're right. That's a problem. I guess this means appearance:base
really is a separate thing that we'd need to spec out for all pre-existing controls all at once. And in a given browser, likely all of them would need to be enabled at the same time, to avoid compat issues cropping up in the interim. That's unfortunate - it'll make appearance:base
a tough thing to ship - any ideas to mitigate that "all at once" problem?
In the meantime, I think I'm convinced that <input type=checkbox switch>
shouldn't be blocked on appearance:base
. So from my point of view what's left to do is to finish spec'ing out the pseudo classes and styling rules mentioned in https://github.com/whatwg/html/issues/4180#issuecomment-1824127126.
That's unfortunate - it'll make appearance:base a tough thing to ship - any ideas to mitigate that "all at once" problem?
Yes, the mitigation for this exact issue was proposed during the initial discussions about base
and rejected - it's to mint a bunch of names, one per control, and only allow them to be used on the correct control. That is, appearance: base-switch
, which activates the "base" appearance for switch controls only - on any other element it does nothing. And similarly, base-checkbox
/etc for all the others, which can be minted and shipped independently, and tested via @supports
independently.
It's a little annoying since you can't turn them all on at once later on when they're all supported, nor can you apply them widely to your page across several controls (you have to specify each for the appropriate control, in N separate rules), but there are some mitigations we could apply. For example, we could allow multiple base-*
keywords and trigger the base styling if any of them are appropriate for the element, so you could drop an input { appearance: base-switch base-checkbox base-radio; }
in your page and upgrade all of them at once. And when we're done we could always go ahead and mint the plain base
keyword that does turn them all on; we'd just have to make sure to add new base values for any new controls as we add them, and that's a reasonable thing to require as part of the (rare) design process for a new control type.
Yes, the mitigation for this exact issue was proposed during the initial discussions about
base
and rejected
Well this approach sounds perfect to me - it allows individual shipment and even individual progressive enhancement via @supports
. Can you say more about (or link to) why this path was rejected?
Hm, it might not even have been rejected, per se, just accidentally dropped. https://github.com/w3c/csswg-drafts/issues/5914#issuecomment-776104777 is the minutes of the discussion where I suggested this exact approach, and nobody seems to have objected during that meeting.
(Tho note the later discussion in https://github.com/w3c/csswg-drafts/issues/5998#issuecomment-816302367, where the CSSWG concludes it would be better to do the "base" switch via an attribute on the element, rather than via appearance
. This is because it's cleaner to change Shadow DOM based on HTML information rather than CSS information.)
input { appearance: base-switch base-checkbox base-radio; }
Would this also adjust the shadow DOM, or the base UA styles?
That's the question that was debated in 5914/5998, yes.
Hm, it might not even have been rejected, per se, just accidentally dropped. w3c/csswg-drafts#5914 (comment) is the minutes of the discussion where I suggested this exact approach, and nobody seems to have objected during that meeting.
(Tho note the later discussion in w3c/csswg-drafts#5998 (comment), where the CSSWG concludes it would be better to do the "base" switch via an attribute on the element, rather than via
appearance
. This is because it's cleaner to change Shadow DOM based on HTML information rather than CSS information.)
Thanks for those links - I'm now sad that I missed those meetings. And I'm sorry for rehashing part of that conversation in the comments above. But I'm ok/supportive of the conclusion that we need to use an attribute to opt in to interoperable/new styling, and that there should be a CSS pseudo class that matches when an element supports the attribute.
Anyway, that would seem to be a good solution that can be rolled out control-by-control. Given that, it sounds like it would make sense to build <input type=checkbox switch base>
as part of the current pull request?
@annevk @nt1m I've tested and found that the iOS native switch can be used to toggle state with a left or right TouchMove, is this supported in the WebKit implementation?
That is, is there any difference in the interaction between the current <input type=checkbox switch>
in WebKit and the iOS native switch?
This is a feature request on the behalf of all web developers targeting mobile. Here are reasons the toggle switch element should be natively available in HTML forms:
I am happy to help writing a spec for the
<input type="switch" />
element if that can help getting it into the browsers.