Or: ‘Why UI libraries exist’
In working with web forms, the same sorts of edge cases seem to appear repeatedly, and (at least) I find myself waffling on how to approach them with JavaScript.
I feel better not reinventing the wheel, and just normalizing the cross-browser differences.
It's hard to avoid reinventing the wheel
The timing and intercepting of validation events feels hacky at best, yet I feel sloppy ignoring the browser's built in input validation. That being said, input validation is not consistently supported, not does it behave predictably. Also the UX leaves a lot to be desired, with forms opting to wait until an entire form has been submitted, rather than validating inline.
Binary validation isn't enough
The form and input specs only provide 2 values for validity state: :valid and :invalid, which are only evaluated after the input has had onBlur triggered as a target, unless it's also marked as :required which is evaluated on submit as :invalid.
However: this is not always true.
"an empty string means the constraint is satisfied".
I have seen folks like @joshblack use Objects like Enums with 4 states, which seems like a much better idea.
'valid' | 'invalid' | 'validating' | 'initial';
We have CSS pseudo-classes for things like :out-of-range for min- max ranges, and :indeterminate for half-filled checkboxes, but not a breakdown of pseudo-classes for validity of initial states.
The DOM method of event.target.validity is read-only, as is the ValidityState method. The latter is a real bummer, because that could be super useful.
You can only read from checkValidity() as well. There's no programmatic way in the browser to force set a field's validity. Sure, you can start juggling classes like .invalid, .required, etc. but I can assure you: that is a guaranteed path to madness.
In a handful of browsers, setCustomValidity() sounds like a great idea, but it's only setting the content of the browser's default field validation message.
"There is no standard way to change their look and feel with CSS."
What about accessibility?
None of the aforementioned even touches how radically-inaccessible all of this is. Because of all the wheel reinvention needed to make inputs a reasonably-painless experience and consistent across various contexts, we've totally munged the native affordances given to us by HTML. This leads devs who care and notice to start applying attributes like aria-live, and accessibility experts to pull out their hair.
We have to do better.
Smarter defaults
Here are some ideas on how to improve developer and user experience at the W3C standards level.
- Automatically disable
autocorrect,autocaptialize, onemail,url,password, and every otherinput typethat isn'ttextorsearch.
Ditch
placeholder, repurpose them to static input masks.
Ditch
passwordmasking. At the very least, include ahide passwordUI control.- Use this same input type for captchas.
- Introduce
input type="fingerprint". Native mobile operating systems are already doing this.
Introduce UI counterparts on the Web for inputs that were born on native mobile interfaces.
- Toggles. Binary—on or off.
- Segmented controls. Perhaps a type of
radiobutton orselect. geolocationinput type. We already have geolocation APIs. Why not standardize the inputs?stepattributes could allow finer-grained controls.- Default form CSS to mobile-first styling
- Large, separated touch targets
- Picker menus instead of separate
inputs formonth,day,time, etc.
Make time data more intelligent
- Introduce
birthdatetypes that automatically setmaxto youngest acceptable age for a given site's terms of service, avoiding "are you really from the future?" messages.
- Introduce
- Define consistent relative times and dates for
timeinputs and elements. See moment.js for a great example of what a baseline API for this should look like.
Provide validation APIs more control and much less boilerplate when it comes to custom client-side validation.
- Define validation errors as attributes on input elements
- Add the option to specify custom messages per ValidityState, including defining custom ones.
Allow the developer to choose when validation occurs
- Default to inline validation with a 2 second debounce, and/or
onBlur()
- Default to inline validation with a 2 second debounce, and/or
Allow overriding CSS for browser validation error message popovers
Introduce
cameraandmicrophoneinput types to make speech and media input easier.Explicitly separate
valueand addinitialValue(see React.js'sdefaultValueattribute for why this makes sense)Eliminate the confusion created using scenarios such as the following:
<input type=text inputmode=numeric>(triggers numeric software keyboard) vs.<input type="number">(does not trigger numeric software keyboard)
<input type="number">should automatically haveinputmode="numeric"andpattern="[0-9]*" set, and thestepUI should be explicitly enabled/disabled.
Don't force
inputelements to be wrapped bylabelelements to gain larger hit areas. Accessibility: yes! Markup hacks: no!<input type="emoji">. With the number of "reaction" UIs cropping up, this only makes sense.Consider custom keyboards Sure, it seems scary, and lots of dangerous things could be done. All I'm asking is to consider it. There is also a lot of good that can be done as well.
What do you say, W3C?
These are just a few improvements and suggestions for better developer and user experience. Let's make them happen.