whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.17k stars 2.69k forks source link

<input type=checkbox switch> #4180

Open atishay opened 6 years ago

atishay commented 6 years ago

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.

Toggle Switch

annevk commented 6 years ago

Shouldn't this be a checkbox with a different style? E.g., appearance: switch?

cc @whatwg/rendering

atishay commented 6 years ago

Definitely makes more sense as we get backwards compatibility.

annevk commented 6 years ago

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.

domenic commented 6 years ago

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.

sideshowbarker commented 6 years ago

👍 It also seems worth mentioning that ARIA (since ~1.1 I think) now has a switch role:

https://w3c.github.io/aria/#switch

atishay commented 6 years ago

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.

annevk commented 6 years ago

@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

LJWatson commented 6 years ago

The ARIA 'switch' role maps to the accessibility APIs, so an element with 'role="switch"' has semantic meaning to screen readers.

malchata commented 6 years ago

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.

annevk commented 6 years ago

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.

malchata commented 6 years ago

Good point @annevk. I can't see any reason why that wouldn't work as well!

atishay commented 5 years ago

There seems to be no progress on this issue for some time. Is there any way I can help?

annevk commented 5 years ago

@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.

smaug---- commented 5 years ago

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.

domenic commented 5 years ago

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.

atishay commented 5 years ago

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:

  1. Shadow DOM cannot be attached to an <input> tag.
  2. We can place an input type checkbox inside a shadow of a regular element, but that would have weirdness with <label for="">. We will have to synchronize values on click and name properties.
  3. This can be implemented as a custom element without the shadow DOM by injecting the ::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.

tkent-google commented 5 years ago

@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

domenic commented 5 years ago

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.

atishay commented 5 years ago

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.

atishay commented 5 years ago

Is there something else that can be done to get some progress in getting a toggle switch element?

atishay commented 5 years ago

@domenic Do we need anything else? Is there still interest in building something in this area?

tkent-google commented 5 years ago

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

gregwhitworth commented 5 years ago

@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.

domenic commented 5 years ago

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.

tkent-google commented 5 years ago

I opened a WICG thread for this. https://discourse.wicg.io/t/proposal-a-toggle-switch-control-element/3620

tuespetre commented 5 years ago

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.

atishay commented 5 years ago

@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.

tuespetre commented 5 years ago

@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.

tuespetre commented 5 years ago

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.

alystair commented 4 years ago

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

About the POC

Since it's an alternative styling to 'checkbox', implementation wouldn't be as difficult as creating an entirely new input type.

Screenshot

image

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.

Wildebrew commented 3 years ago

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.

nuxodin commented 3 years ago

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

tkent-google commented 3 years ago

FYI. Google gave up standardizing this.

gregwhitworth commented 3 years ago

@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.

annevk commented 1 year ago

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----?

hidde commented 1 year ago

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.

annevk commented 1 year ago

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.

hidde commented 1 year ago

Fair enough, agreed appearance: none is fine as it provides full control.

mfreed7 commented 1 year ago

This was just discussed at OpenUI: https://github.com/openui/open-ui/issues/338#issuecomment-1673745778

annevk commented 12 months ago

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.

mfreed7 commented 11 months ago

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?

annevk commented 11 months ago

How would we enable it in a way such that we don't claim support for appearance:base for other controls?

mfreed7 commented 11 months ago

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.

tabatkins commented 11 months ago

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.

mfreed7 commented 11 months ago

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?

tabatkins commented 11 months ago

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.)

gregwhitworth commented 11 months ago

input { appearance: base-switch base-checkbox base-radio; }

Would this also adjust the shadow DOM, or the base UA styles?

tabatkins commented 11 months ago

That's the question that was debated in 5914/5998, yes.

mfreed7 commented 11 months ago

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?

yisibl commented 10 months ago

@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?