Skip to content

[css-selectors-4] :user-invalid and :user-valid should not require a blur event to trigger #9583

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
argyleink opened this issue Nov 9, 2023 · 8 comments
Labels
selectors-4 Current Work

Comments

@argyleink
Copy link
Contributor

I think we should remove this line from the spec: and changed the focus to another element.

The goal of this selector is to signal a user has actually touched (focused in) and changed the value of the input. It has nothing to do with blur or moving to another input. It's more about a hook for authors to know it's a good time to show the validity of the input because a user has "tried" something.

Before :user-valid, the signal was premature, sent on form load, before a user has had a chance to interact, showing errors states when they havent even done anything.

https://codepen.io/web-dot-dev/pen/wvNJGrO

In the above demo, each input is empty and invalid. Type some information, it becomes valid, but should additionally be user-valid, not awaiting blur to trigger. Furthermore, browsers do the proposed behavior in this issue, but only after blur; meaning subsequent interactions with the input do realtime trigger user-invalid and user-valid. I'm proposing this is how it always is, and isn't gated by a one time blur event. I'm also pointing out that the implementations from browsers seem confused on the spec prose as well, only respecting the "changed focus" clause on interactions before blur, not after. This proposal change would make the behavior consistent and more desirable to authors.

@josepharhar
Copy link
Contributor

@nt1m

@bramus
Copy link
Contributor

bramus commented Nov 9, 2023

If the "change focus" part gets removed it would need some other trigger to activate: you definitely don't want the email input to nag about it being invalid while you are still typing in your e-mail address (as that would defeat the purpose of the selectors).

What could work is adding some debounced activation that triggers after one has stopped interacting with the control (e.g. pause typing). That could be in addition to blurring it.

@nt1m
Copy link
Member

nt1m commented Nov 9, 2023

I cocur with @bramus. :user-invalid / :user-valid are linked to the change event because that's when the value is committed. Doing it on every keypress would be very disruptive for users. An alternative definition could use debounce as @bramus says but it would generally be harder to define with not necessarily huge benefit.

The CSS spec says "and changed the focus to another element". I think that's not necessarily always accurate and should probably say something like "has committed a new value" or such. But I don't think that sentence matters a lot either way since it's an example and not normative.

@argyleink
Copy link
Contributor Author

on every keypress would be very disruptive for users

but it still does this, just after the initial await for blur. should it stop doing that then, and always be blur?

Kapture.2023-11-09.at.14.19.32.mp4

i expect :user-* to be tied to users interacting with it, not "completing" their edits or "leaving" the field.

for a while now javascript libraries have offered even more queues (dirty, touched, pristine) for authors to use, css is barely catching up and doing mixed things

@nt1m
Copy link
Member

nt1m commented Nov 9, 2023

This is something @pxlcoder and I discussed, and we think it's better for users to get live feedback when they are correcting their values, but just not when they are initially typing it. If we always waited for a blur even after the initial value was typed, it'd be actually be annoying to the user to not get feedback on whether the correction is valid.

:user-valid / :user-invalid are just meant to address the annoyances of :valid / :invalid. Its definition is solely based around that.

@SebastianZ
Copy link
Contributor

UX is key here and it looks like browsers have different approaches to this.

Here's a simple test case similar to @argyleink's one: https://jsfiddle.net/SebastianZ/6mrojuet/
They differ when the value is valid, you blur, then focus again and make the value invalid again.
In that case, Chrome matches :invalid, :user-invalid while Firefox matches :invalid, :user-valid. So Firefox tries to be smart and resets the behavior back to the initial one in case the value gets invalidated when the user focuses the field again. Though when it's the other way round, i.e. the value is invalid, you focus the field again and enter a valid value, :user-valid matches immediately.
(Maybe someone can provide the behavior in Safari to see whether it behaves differently.)

From the user's perspective, I believe Firefox' behavior makes sense.

It should be clarified whether there are use cases in which authors need control over that behavior. And regarding debouncing, I want to point out that some users type slower than others. So people might then get a different UX depending on their writing speed. I don't believe that's something desirable.


That aside, if we decide that authors should get more control over that, one way to address this would be adding :valid() and :invalid() pseudo-class functions which take a parameter defining the behavior, e.g. dirty, touched, and pristine as @argyleink mentioned.

In that case, we should then also think about extending the Validation API so that Web Components can make use of that as well.

Sebastian

@SebastianZ
Copy link
Contributor

Btw. there's also a separate discussion in #1533 about adding a pseudo-class matching when a user has changed the field value.

Sebastian

@fantasai fantasai added the selectors-4 Current Work label Jan 9, 2024
@waterplea
Copy link

@argyleink brings up a good point, I too came from Angular world and would love to see native :touched as well as :dirty that was linked above by @SebastianZ

I was surprised to see that :user-invalid does not trigger on blur on required inputs, it only does so when I type a value and then clear it manually before blur. That's not a good UX — user should be notified they forgot the required value when navigating through the form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
selectors-4 Current Work
Projects
None yet
Development

No branches or pull requests

7 participants