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

Use :user-invalid and :user-valid pseudo-classes to indicate visually when client-side validation has failed for an input after user interaction #621

Open
bobby opened this issue Oct 10, 2024 · 4 comments

Comments

@bobby
Copy link

bobby commented Oct 10, 2024

Describe the issue

This issue is a follow-on to #47, but proposes the use of :user-valid and :user-invalid pseudo-classes in addition to the aria-* attributes to apply valid/invalid styles to an input.

Current Behavior

Currently, when doing client-side validation using HTML attributes (no JavaScript), an invalid user input entry is not highlighted visually.

Expected Behavior

I would expect client-side validated inputs with which the user has interacted (indicated by the :user-valid or :user-invalid pseudo-classes) to show the proper validation styling.

Reproduction URL

https://jsfiddle.net/L2p4rmy1/1/

Environment

As linked above, the necessary pseudo-classes are supported across all major browsers.

@Yohn
Copy link

Yohn commented Nov 13, 2024

CodePen

Note

Codepen Example has validation working for all input types except button, submit, reset, and select multiple types. I might add the select multiple types validation later, but for now its not there.
For validating file input types, the browser does not validate the accept or size attributes, so I made a javascript validation class to validate file inputs based on the [accept] and [data-max-size] attributes on the file tag. It will also list the files selected under the file element with an image preview if the file is an image.


Heres some basic quick css to make this work for :user-valid and :user-invalid

input:user-valid,
input:user-invalid {
	padding-right: calc(1.5em + .75rem);
	background-repeat: no-repeat;
	background-position: right calc(.375em + .1875rem) center;
	background-size: calc(.75em + .375rem) calc(.75em + .375rem);
}
textarea:user-valid,
textarea:user-invalid {
	padding-right: calc(1.5em + .75rem);
	background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem);
	background-repeat: no-repeat;
	background-size: calc(.75em + .375rem) calc(.75em + .375rem);
}
input:user-invalid,
textarea:user-invalid {
	border-color: var(--pico-form-element-invalid-border-color);
	background-image: var(--pico-icon-invalid);
}
input:user-valid,
textarea:user-valid {
	border-color: var(--pico-form-element-valid-border-color);
	background-image: var(--pico-icon-valid);
}

And then to add the text after the element you can put a <small data-invalid="This is invalid" data-valid="validation passed!"></small> after the element

/********** To include a message after the element with info ************/
input:user-valid + small[data-valid]::after,
textarea:user-valid + small[data-valid]::after {
	content: attr(data-valid);
	color: var(--pico-form-element-valid-border-color);
}
textarea:user-invalid + small[data-invalid]::after,
input:user-invalid + small[data-invalid]::after {
	content: attr(data-invalid);
	color: var(--pico-form-element-invalid-border-color);
}

input:user-valid + small[data-valid]::after,
input:user-invalid + small[data-invalid]::after,
textarea:user-valid + small[data-valid]::after,
textarea:user-invalid + small[data-invalid]::after {
	display:block;
}

@Yohn
Copy link

Yohn commented Nov 13, 2024

After playing with this some more, I've realized it will take more css to completely ensure the invalid and valid states are correct.
Input checkbox and radio types need to be accounted for, probably file and reset as well.
Select needs to be accounted for.
I'll be playing with my codepen for a little while to add these other form input types to ensure compatibility with them all, and will edit/update when completed.

@walterdavis
Copy link

When I have fought with this in the past, I ended up using CSS to change .field_with_errors to display: inline. That's a big hammer, and clearly not going to fix everything that redefining the proc would do. But as a quick fix, it does keep the layout intact when an additional div (with implicit block display) is layered into the layout from breaking up those special formatting contexts.

@Yohn
Copy link

Yohn commented Nov 13, 2024

When I have fought with this in the past, I ended up using CSS to change .field_with_errors to display: inline. That's a big hammer, and clearly not going to fix everything that redefining the proc would do. But as a quick fix, it does keep the layout intact when an additional div (with implicit block display) is layered into the layout from breaking up those special formatting contexts.

check this out
I added a validation.scss to my fork and it seems to be working great. The codepen above has most of it in there as well in the plan css. And using the <small data-invalid="error message" data-valid="validation passes on the front end"> tags for the error message, just gotta put the small tag after the element to validate.

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

No branches or pull requests

3 participants