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 Enum
s 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 type
that isn'ttext
orsearch
.
Ditch
placeholder
, repurpose them to static input masks.Ditch
password
masking. At the very least, include ahide password
UI 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
radio
button orselect
. geolocation
input type. We already have geolocation APIs. Why not standardize the inputs?step
attributes could allow finer-grained controls.- Default form CSS to mobile-first styling
- Large, separated touch targets
- Picker menus instead of separate
input
s formonth
,day
,time
, etc.
Make time data more intelligent
- Introduce
birthdate
types that automatically setmax
to 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
time
inputs 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
camera
andmicrophone
input types to make speech and media input easier.Explicitly separate
value
and addinitialValue
(see React.js'sdefaultValue
attribute 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 thestep
UI should be explicitly enabled/disabled.
Don't force
input
elements to be wrapped bylabel
elements 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.