Skip to content

[css-forms-1] Password visibility toggle #11845

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

Open
kbabbitt opened this issue Mar 5, 2025 · 21 comments
Open

[css-forms-1] Password visibility toggle #11845

kbabbitt opened this issue Mar 5, 2025 · 21 comments

Comments

@kbabbitt
Copy link
Collaborator

kbabbitt commented Mar 5, 2025

https://drafts.csswg.org/css-forms-1/#field-pseudos has the following inline issue:

Define something for the password visibility toggle for user agents implementing it?

I'd like to see this. We currently have ::-ms-reveal implemented in Edge Chromium for compat with Edge Legacy and Internet Explorer. It would be great to get it on a path to standardization.

See also: whatwg/html#7293

@hober
Copy link
Member

hober commented Mar 6, 2025

See also #6788

@lukewarlow
Copy link
Member

lukewarlow commented Mar 6, 2025

for user agents implementing it.

I'm also slightly concerned by this phrasing? Is this more talking about the appearance: auto case?

Base appearance controls should either implement this or not across UAs. (My preference is for it to be included as part of the base appearance).

@nt1m
Copy link
Member

nt1m commented Mar 8, 2025

My main reason for not initially including it initially was because of compat concerns (some sites would end up with two password icons when Mozilla tried adding this).

One thing that could be considered is including it for appearance: base, but I don't think this approach makes a lot of sense, given that users should be able to benefit from this by default without needing sites to opt-in.

@kbabbitt Is Chromium planning to ship this by default anytime soon? On hindsight, it's probably quirkable, but
I think it would alleviate some of the compat concerns to have Chrome ship some version of this initially.

I'd be happy to add something like this to the draft though.

@lukewarlow
Copy link
Member

lukewarlow commented Mar 8, 2025

I suspect the two toggle issue can be mostly solved by aliasing to ::-ms-reveal which many sites detect and act appropriately (either setting display to none or hiding their own UI).

For some reason Firefox never seemed to try this (though I may have missed it).

@mfreed7
Copy link
Contributor

mfreed7 commented Mar 10, 2025

Chromium also encountered compat issues with trying to add ::reveal about 5 years ago, but I think the compat issues are alleviated by the appearance:base opt-in, correct? I'm also in favor of supporting a "reveal" button - this is a very common pattern on the web.

@kbabbitt Is Chromium planning to ship this by default anytime soon? On hindsight, it's probably quirkable, but

For the compat issues mentioned, I don't believe there are plans to ship this, without the opt-in.

@lukewarlow
Copy link
Member

Out of interest did chrome's compat analysis look into the ::-ms-reveal pseudo element and how that might change things?

It's somewhat a chicken and egg problem because without a pseudo to target sites can't feature detect and do the right thing here. The only browser that did/does have that is IE/Edge. How does Microsoft handle that compat issue currently?

@kbabbitt
Copy link
Collaborator Author

For ::-ms-reveal the author can set display: none to suppress the built-in button. I'm not sure whether that was considered for the standardized version. cc @sanketj who might have more context.

@lukewarlow
Copy link
Member

I think it should definitely be doable even if we don't encourage it (because the browser can probably better handle various mechanics I know the MS one has a lot of thought put into the behaviour). But in the thing of fully stylable we should definitely allow it to happen.

I personally have always feature detected it and hidden my custom one when it existed. But others equally might hide the built-in one. Either situation would alleviate compat issues with double buttons.

It would be unfortunate to gate it on appearance: base but if that's necessary then so be it.

@sanketj
Copy link
Member

sanketj commented Mar 10, 2025

+1 that a reveal button for <input type='password'> should be supported - it is a very popular pattern on the web! I like the idea of having a standardized version be a part of appearance: base. We'd need this standardized password reveal button to be easily customizable and also easily turned off, I can see developers wanting to do both.

@nt1m
Copy link
Member

nt1m commented Mar 10, 2025

My take is that it's unfortunate to gate this behind appearance: base. This is an UX improvement that would generally be good for all users, so I'd rather have this be opt-out rather than opt-in. Other than that, yes, I agree we should do this, and that there should be a way to disable this (perhaps ::reveal { display: none } is fine for that.

@lukewarlow
Copy link
Member

lukewarlow commented Mar 11, 2025

I guess ultimately appearance: auto is UA defined so it's kinda up to browsers to decide what to do.

One issue with having it in only one mode is it would break feature detection such as the one I've previously used, leading to neither the UA button NOR my custom one. (From memory)

@supports selector(::-ms-reveal /*::reveal*/) {

}

@mfreed7
Copy link
Contributor

mfreed7 commented Mar 11, 2025

So in 2020 Blink did a "form controls refresh" which was a joint project between Chrome and Edge. As part of that project, we did actually add a ::reveal pseudo element for <input type=search> and we tried to ship it. However, we got several compat bugs reported (e.g. this one), enough that we decided to re-disable the ::reveal pseudo element. Microsoft was able to successfully ship it as ::ms-reveal at that point.

The compat problems all stem from (existing) sites that have their own "reveal" button. The UX is very confusing to users when two separate reveal buttons are present. It's a relatively-easy fix for such sites, just setting display:none on the pseudo element to hide it. But still there were enough of them that we weren't comfortable shipping the feature back then. But I think with an opt-in like appearance:base, it should be a great addition to the platform.

@lukewarlow
Copy link
Member

Microsoft was able to successfully ship it as ::-ms-reveal at that point.

Sorry to be really specific here, did chrome try with that alias and Google ultimately had a different risk appetite to Microsoft? Or did Google not try to use that. If we can have that as a compat alias and it solve the issue that feels like a great way to go.

Failing that yes having it in appearance: base and maybe in appearance: auto but with a default display: none; (so it can be opted into without all of appearance base), seems like an okay tradeoff.

@mfreed7
Copy link
Contributor

mfreed7 commented Mar 11, 2025

Sorry to be really specific here, did chrome try with that alias and Google ultimately had a different risk appetite to Microsoft? Or did Google not try to use that. If we can have that as a compat alias and it solve the issue that feels like a great way to go.

No, Chrome has a policy of not shipping vendor prefixes, so it was ::reveal or nothing. And due to compat (and general risk reduction to be able to ship the rest of the project), we went with nothing. I'm still very supportive of a ::reveal pseudo, as long as we can do it compatibly.

@lukewarlow
Copy link
Member

I think we might need input-security as a property to explain how this password reveal mechanism works to some extent? Though perhaps only exposed to UA stylesheets? Perhaps we can just define the behaviour and leave this specific situation up to the UA to decide how to implement (with some limitations such that the input type can't be toggled to text or something like that)?

@kbabbitt
Copy link
Collaborator Author

It sounds to me like we at least have consensus to have it in appearance: base? And maybe also to allow UAs to expose it in appearance: auto if they so choose?

@nt1m
Copy link
Member

nt1m commented Mar 28, 2025

It sounds to me like we at least have consensus to have it in appearance: base? And maybe also to allow UAs to expose it in appearance: auto if they so choose?

Yeah I like that. My proposal after talking to more folks internally:

  • The pseudo-element is just always there in the pseudo-element tree
  • It is named ::reveal-icon or ::reveal (up for bikeshedding)
  • For appearance: auto in UAs that do not want it by default, this gets display: none !important by default (auto style should match the platform)
  • For appearance: none (or implicit none appearance) in UAs that do not want it by default, this gets display: none (so developers can choose to show it)
  • For appearance: base: this gets the same display by default in all UAs, whether it's none or inline-block/block is up for discussion, but it should be predictable in all UAs.
  • (optional: allow ::-ms-reveal as an alias for maximum compatibility for UAs that enable it by default)

@kbabbitt
Copy link
Collaborator Author

  • For appearance: auto in UAs that do not want it by default, this gets display: none !important by default (auto style should match the platform)
  • For appearance: none (or implicit none appearance) in UAs that do not want it by default, this gets display: none (so developers can choose to show it)
  • For appearance: base: this gets the same display by default in all UAs, whether it's none or inline-block/block is up for discussion, but it should be predictable in all UAs.

I guess I'm curious what you had in mind in terms of implementing these? It sounds like it would make the cascaded value of display dependent on the cascaded value of auto, and properties can't really depend on each other like that.

The compat issue, as I understand it, is that the ::reveal pseudo conflicted with existing site-provided reveal buttons. So what I had in mind was that ::reveal would parse and cascade as normal for all appearance values, but if the UA doesn't want to expose a built-in control for appearance: auto then the pseudo would have nothing to target, and thus there would be no visible effect.

(This is what Edge does for the ::-ms-clear selector. Internet Explorer and Edge Legacy had a "clear text" button which that selector targeted. The button has since been removed, but we had to continue parsing the selector to avoid breaking existing content.)

@nt1m
Copy link
Member

nt1m commented Mar 28, 2025

I guess I'm curious what you had in mind in terms of implementing these? It sounds like it would make the cascaded value of display dependent on the cascaded value of auto, and properties can't really depend on each other like that.

WebKit has a step in the StyleAdjuster that can adjust styles based on the appearance value. Chrome has a method at least to adjust styles based on appearance: base so I imagine it's not impossible to make it happen for auto or none.

@mfreed7
Copy link
Contributor

mfreed7 commented Mar 31, 2025

I guess I'm curious what you had in mind in terms of implementing these? It sounds like it would make the cascaded value of display dependent on the cascaded value of auto, and properties can't really depend on each other like that.

WebKit has a step in the StyleAdjuster that can adjust styles based on the appearance value. Chrome has a method at least to adjust styles based on appearance: base so I imagine it's not impossible to make it happen for auto or none.

Right - we had to solve this problem for customizable-<select>. See, e.g., all of the UA rules that have -internal-auto-base(), such as this one. It should be possible to modify that to account for none also.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-forms-1] Password visibility toggle, and agreed to the following:

  • RESOLVED: Adopt a pseudo-element representing the password reveal icon control. Make it 'display: none' by default in 'appearance:none'; match platform convention in 'appearance:auto', and displayed in 'appearance:base'. Name TBD.
The full IRC log of that discussion <fantasai> ntim: MSFT Edge ships a password visibility toggle. It's an icon that reveals the password in plain text
<ntim> https://github.com//issues/11845#issuecomment-2760207097
<fantasai> ntim: I proposed adding a standardized pseudo for this
<fantasai> kbabbitt: The Edge feature is a vendor extension, would like to standardize
<fantasai> kbabbitt: We tried to implement in Blink , but ran into compat problemns
<fantasai> kbabbitt: Would like sites to be able to opt into it
<fantasai> kbabbitt: One change I might want to suggest ot Tim's proposal is the `display: block` but can leave to future discussion
<fantasai> ntim: Thoughts?
<fantasai> dholbert: Is this the first case where appearance:base provides a component not available in default styled component?
<fantasai> ntim: The button would always be present in the pseudo-element tree
<fantasai> ntim: Just, depending on 'appearance', the default 'display' would be different.
<fantasai> astearns: But some implementations don't have this button at all?
<fantasai> dholbert: feels strange that 'appearance:base', at least visually, *adds* something.
<fantasai> dholbert: it does seem like a nice way to go back and add something that should have been there in the first place
<fantasai> dholbert: website with existing control might be surprised to get the new control when applying 'appearance: base'
<dbaron> (as a user, I want reveal buttons on all password fields whether or not the site wanted it)
<astearns> +1 dbaron
<fantasai> fantasai: I'm not too worried about that particular scenario. 'appearance: base' causes changes, should be checking your site to see if you're happy with those changes
<dbaron> (particularly when entering passwords on my phone)
<lea> agreed with fantasai
<fantasai> ntim: I wanted to leave 'appearance: auto' to the UA, to match platform conventions. And some platforms don't have this button.
<fantasai> ntim: I have less strong opinions about 'appearance: none'; but for compat we might want to hide it by default.
<fantasai> lea: This pseudo would not be present if the UA doesn't implement the functionality
<fantasai> ntim: Ideally it would be present in all the UAs.
<lea> q?
<lea> q+
<fantasai> ntim: Just that in 'appearance: auto', up to UA whether to show or not
<fantasai> ntim: but in 'base' it's consistent -- always get the button by default
<fantasai> lea: 2 things. Whether impl has password reveal or not. And whether visible or not.
<fantasai> lea: if impl doesn't impl, then pseudo shouldn't exist
<astearns> ack lea
<fantasai> ntim: Problem with different UAs doing different things is lack of consistency. Not interoperable.
<fantasai> ntim: developer tests in one browser, works; other browser doesn't work, this is bad
<lea> q?
<lea> q+
<fantasai> ntim: If they start by building site on browser without password reveal, and add a custom one, and suddenly a browser changes to add by default -- now have double reveal icons, also not great
<fantasai> ntim: So we want to be consistent at least for 'appearance:base'
<astearns> ack fantasai
<TabAtkins> fantasai: if the UA doesn't implement the reveal button, then obviously it should not claim to support the pseudo
<TabAtkins> fantasai: but we're saying that all UAs *should* implement this, it's a required part of the spec
<TabAtkins> fantasai: and to match paltform conventions, appearnace:auto (the default), the UA would be able to hide the reveal
<TabAtkins> fantasai: but the pseudo exists and is implemented
<TabAtkins> fantasai: and Tim is proposing that in the defaults, appearance:auto gives you platform convention, appearance:none has it turned off for compat, and appearance:base has it turned on. this makes it obvious to authors that it exists in the first place.
<astearns> ack lea
<TabAtkins> fantasai: otherwise it's more likely that authors will design a custom version that they dont'a ctually need
<lea> No objection to hiding it in auto if the capability is implemented. I don't think there is a precedent where UAs must add something even for standards they don't implement. E.g. what does a UA do if they actively oppose a certain standard? Still implement the pseudo? What about pseudos that were added after appearance: base? Of course the trees will be different.
<dholbert> (For reference, I've got screenshots of double 'reveal' icons from when Firefox tried to ship a reveal icon by default (for `appearance:auto`) a few years back: https://bugzilla.mozilla.org/show_bug.cgi?id=1754086 . Based on experience there, I think backwards-compat definitely likely requires UAs to hide the button with `appearance:auto` and `appearance:none`)
<TabAtkins> fantasai: it's a violation fo the css spec to treat syntax as valid for a featur eyou don't support
<TabAtkins> lea: oh, i thought that's what tim was proposing
<TabAtkins> fantasai: nope
<TabAtkins> lea: sorry, misunderstood
<fantasai> astearns: Are we resolving on Tim's proposal?
<bkardell> s/ featur eyou / feature you /
<fantasai> astearns: further litigate details in future?
<fantasai> ntim: Add also to make visible by default, not in the comment.
<fantasai> astearns: proposed to adopt Tim's proposal, and define it as visible in 'appearance: base'
<kbabbitt> q+
<fantasai> ntim: Might want to decide on a name. `::reveal` or `::reveal-icon`
<fantasai> ntim: Many pseudo elements in the current draft that are -icon
<lea> q+
<astearns> ack kbabbitt
<dholbert> q+
<astearns> ack lea
<fantasai> kbabbitt: prefer ::reveal because similar to MS-prefixed version, but no objection either way
<fantasai> lea: How does someone detect whether the password is revealed or not?
<fantasai> fantasai: This doesn't tell whether revealed or not, just is a pseudo-element for the icon
<fantasai> lea: I suspect in many cases authors will want to style the icon differently based on whether in revealed state or not
<fantasai> lea: we should decide names together
<jensimmons> +1 for not deciding in isolation!
<fantasai> ntim: so :reveal?
<astearns> ack dholbert
<ntim> :revealed
<lea> `:revealed::reveal` then doesn't really work
<fantasai> :password-show :password-hidden
<dbaron> +1 to `:revealed` as a pseudo-class name
<fantasai> dholbert: So having computed value of 'display' depends on computed value of 'appearance'
<fantasai> dholbert: I don't like computed value dependencies very much... defer to emilio
<fantasai> dholbert: action at a distance is not great
<fantasai> dholbert: but maybe it's fine
<astearns> ack fantasai
<TabAtkins> fantasai: since we have a bunch of -icon we should be consistent and use ::reveal-icon
<TabAtkins> fantasai: for the pseudo-class, hadn't thought of it before
<fantasai> PROPOSED: Adopt a pseudo-element representing the password reveal icon control. Make it 'display: none' by default in 'appearance:none'; match platform convention in 'appearance:auto', and displayed in 'appearance:base'
<fantasai> (Name TBD)
<fantasai> PROPOSED: Adopt a pseudo-element representing the password reveal icon control. Make it 'display: none' by default in 'appearance:none'; match platform convention in 'appearance:auto', and displayed in 'appearance:base'. Name TBD.
<fantasai> RESOLVED: Adopt a pseudo-element representing the password reveal icon control. Make it 'display: none' by default in 'appearance:none'; match platform convention in 'appearance:auto', and displayed in 'appearance:base'. Name TBD.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Tuesday Afternoon
Development

No branches or pull requests

7 participants