Last time I checked, web-browsers today still do not allow you to style the appearance of built-in HTML validation messages [1]; this wouldn't be so bad if Chrome (and Firefox) still conformed to their OS platform UI guidelines (i.e. so it looks system-generated, like how `title=""` tooltips used to be), instead Chrome uses this ugly yellow/orange icon color with black-text on a white background on a bubble with a fixed corner border radius - it clashes horribly with my current project's aesthetics.
Annoyingly, Chrome used to allow styling of validation-messages using vendor-prefixed pseudoelement selectors, but they removed that functionality and never brought it back; I'll chuck this on the same pile as other arbitrary annoyances like "can we have a native HTML combo-box please" and "why is <select multiple> still a horribly unusable ctrl+click box instead of a checkbox-list?".
I think the problem here is not as much with the absence of custom styling, because you can quite easily read the native "validity" state of the input and render it however you want.
The problem is that it's quite tricky to correctly subscribe to the changes of this validity state. There are indeed some validity events being dispatched, but unfortunately not always. Updating form state programmatically (such as calling "form.reset()" or setting input value via "input.value = '...'") doesn't trigger these events.
I think this is a separate good topic for investigations and for suggestions to the web platform
I think form validation should remain an app implemented part of a web form, rather than natively built into the browser.
The majority of the work in form validation is not in the validation of the data, but in the UX and interaction, display and update of state. There's no generic way to handle it, as it's very dependent on the app itself.
Keeping the browser smaller and cleaner, with less logic seems to be a better idea.
Checking if a string is a email (or at least looks like one), if it's a number, etc. is such a cheap processing, that setting up and tearing down a connection to the server to process it is a waste of resources. Client side validation has its uses, it's more responsive. The problem is that we want all these custom behaviors when it's actually some rudimentary data input validation.
I never really understood why people want to style stuff like this. I like how you can express yourself by using colors and layout and stuff like that. But at some point usability is more important than branding.
At work our design team came up with buttons that are 10x10 pixels on my screen. They are used to change pages (like on mobile, but this is a desktop program), the scroll events are ignored by design, so you either click the tiny buttons (which are slightly darker gray than the dark background) or you simulate a finger swipe via drag and drop with the mouse. Yes they designed a touch GUI for a desktop application.
The place where I live is very good at pretending to do the right thing while doing absolutely nothing.
For example a touristic social account managed by some government entity posted some extra complicated wheelchair lift (that will inevitably break in 1 month at most) to show how disabled people are well integrated.
Meanwhile of course the real situation is that people on wheelchair can go almost nowhere at all. Newer public transport has even worse accessibility than before, elevators are mostly broken at all times and regular ramps are missing, doors regularly have super strong springs and a button to open them (which breaks all the time) when they should just have a much weaker spring instead.
Designers I've worked with are like the tourist social media account. Showing the one single place they made accessible and explicitly saying in meetings "we are good people, we care for disabled people"… and then hating me for pointing out the million other things that are not accessible.
Well the ones I've worked with couldn't care less.
Of course they love to show off how good they are to the poor disabled people, but that doesn't mean anything until some government reminds us that we are in breach of contract unless we make our GUI accessible.
Designers that come from a background of human machine interaction care and will say that. Designers who come from a background of art don't understand what is being talked about and so don't say anything - they tend to only ensure it works on their one devices which they have selected to be the best and ignore everything else.
The second group does make things that look nicer, but the first ensures it can be used. You really want both, but then you need to be careful about who wins when they disagree.
It is a patronising sentiment, but adjacent tonal cues suggest GGGP is offering it ironically, thus in ridicule of performative compliance.
On flipside, note that many regulations - in any human domain - are oriented to raise the level of the worst performing, not to support the efforts of the best or to optimise the middle.
Yes very patronising, a terrible attitude really. Which is why I criticise it.
Also I'm disabled myself, although not in a way that requires any adaptation to use a computer. But I of course notice these things a bit more than average; and I get to hear my elderly father's complaints about software that he can't use because of inaccessible design.
Of course a designer should be qualified and notice these things even more… but all they do is move buttons around and disable copy paste so that even fully abled people have a hard time using our software between versions.
I believe that was the commenter's point - that the designers described patronizingly virtue signal about their accessibility priorities, while their other decisions are troublesome.
Which everyone is only doing because it's an industry fad likely stemming from copycatting one or two instances where it was done for legitimate reasons.
People want to style things to match their page, exactly because consistency is part of usability. Especially given the limitations of browser form validations, you will absolutely need your own validations in addition to any browser validations you use. But your own validations will look different from the browser-provided ones, at least on some browsers. Which will confuse users, hence decreasing usability.
And this also assumes that the browser validations are in any way usable to begin with. I would argue that they are not, and would require some sane styling to become usable in the first place.
I think consistency within an application is far more important than consistency across applications. And even if it were true that users hated the lack of consistency, it would fall on deaf ears: the web page developers can only influence their own page. They can't make Google or Mozilla or Apple come up with an actually usable error model, or any kind of good UI in general, so the only chance they have is to create a good UI for their own page, and hide the horrible defaults that each browser is reinventing.
But at some point usability is more important than branding.
I have never worked for any company or organisation that believed this. Most clients will send you their branding guidelines before sending their feature requests. If they get to choose between adding a new feature, improving usability or making sure everything follows the branding, they will choose the branding every time.
I think you're exaggerating here. I recognise the "branding is more important than usability" approach, but the OP specifically said "at some point". Have you ever worked for a company that forced a design decision knowing it would prevent anyone from using the product? I suspect not; there will always be some point.
The issue here is, at what point does usability take precedence. Does input validation fall under "branding" or "function"? IMO, an error modal is nothing to do with company branding, etc. — it's not even part of your document, it's the browser's responsibility. The browser can decide to do something completely different from showing a modal as far as its concerned, so you shouldn't make any assumptions. Your responsibility ends at declaring what valid data is.
It 1000% falls under branding. If you don't make errors consistent across browsers / platforms your support staff will politely but firmly burn your house down. There's no such thing as your responsibility ending and throwing your hands up when you're a company who has to do end-to-end support of your product.
Having as little native anything means you go from
n sets of documentation to 1.
I think the disconnect here is in the interpretation of “more important.” Usability is more important than branding from the point of view of the victims of this kind of over-designed software, the end users. Because they are already being inflicted with a lot of branding, please at least give them conventional error messages.
Sure, but that's not how it works out in practice. It sure looks like everyone just rolls their own. Fun game: can you find any major website that uses the default validation?
This isn't an issue if everyone's an accessibly expert, otherwise we're sacrificing usability.
I love that as well, I hate bloated sites just as the next one here.
But for any more complex form with dynamic content, JS is still inevitable. I guess for HN the input form at the bottom is enough. But Algolia uses a custom input component already.
On reflection my earlier comment was a little off the mark - all 3 of those sites use JavaScript, but minimally.
Zero JavaScript is rarely practical when there's meant to be interactivity of any kind. The issue isn't the language, but the appalling bloat that is now the norm on the web. And, course, bad design in its various forms.
I've found it more annoying to mess with the browser validation API and using setCustomValidity/reportValidity etc. than to just use other validation libs. Ideally I'd use whatever library I want and they would call setCustomValidity for me though.
Using the related pseudo classes :valid, :invalid, :required, :optional is nice, but until last year you still had to do custom logic there because :user-valid/:user-invalid weren't implemented outside of Firefox. That created additional work and was annoying.
Really? In my experience they easily cover the majority of cases - strings versus numbers, min and max length, upper and lower bounds to values, specifying what decimal level you’ll accept, you can even straight up provide a regex in the ‘pattern’ attribute.
I agree with you 100%; I hate it when websites think they’re being trendy by using undraggably-thin scrollbars or try to subvert the UA’s password-manager (banks…) or naively think they can block users right-clicking or copying images.
To clarify my position: I agree that UAs should be free to show validation messages as-appropriate for the user (I.e. those popover hints) but it is because Google decided to stylise them with a very specific aesthetic/design - as opposed to trying to fit-in to the host system - it clashes more. Now, I’m not suggesting that the UA popovers be fully CSS-able, but I would like to see some kind of coarse-grain control “hint” properties - just like we have with (non-WebKit-prefixed) scrollbars, <button>, most <input> types, and more besides. The issue here is that the validation popovers are almost uniquely exempt from styling compared to all other HTML platform features (the only other exception being `title=“”` tooltips, AFAIK).
By-comparison, this is kinda like the (still) half-broken support for dark-mode: if a page is dark-themed you (probably) don’t want nuclear-flash-white UA-provided popovers stinging your eyes because there’s no validation-popover background color hint. Similarly, supposing my website makes tasteful use of serif typefaces - but the input validation popovers will be in Chrome’s own Material-design sans-serif font, while OS/platform widgets will be in some third other font by-default but can generally still be set via CSS. If you’re on HN then you’re likely bothered by inappropriate mixing of serif and sans-serif typefaces, so I hope you can sympathise.
You're talking about millions of dollars of engineering resources to implement what not only doesn't matter, but is probably actually harmful in comparison to the status quo (however ugly that is). And that's just on the implementation side. Now consider the tens of thousands of downstream developers who are going to suck up more resources from their clients because browser developers offered them a new bauble and some knobs to tweak. All going towards something that shouldn't even exist.
I avoid the use of `type=number` and use `type=text inputmode=numeric` instead. It doesn't come with these arrow buttons which most users don't need anyway for entering numbers. Also the keyboard is better on iOS.
But what's crazy is both of those still don't disallow non-numeric input unless you use JS to reject keystrokes and intercept paste. HTML form validation is so incomplete and limited, every time I look at it I want to scream cause wtf there's so many just totally obvious things we need that don't exist by default and we need to reinvent the wheel. Native date and time inputs are still garbage so every UI framework has to build their own solution.
I used to write those fancy textboxes that reformatted your input as a phone number as you type, and intercept paste, and all that.
But then it turns out that you really do want a free-form text input. Let people paste text in, edit their text freely, then let it validate afterwards. When it validates, then reformat it.
For example, text boxes with length limits. These are awful. It messes with your ability to paste something in, then edit it down to the correct length.
Very much this. Live re-structuring runs afoul of tons of things you can't predict.
You can validate roughly anywhere, but at the absolute earliest, only re-format on blur. Never earlier. You have no idea what the user might be doing in the meantime.
And even then, I'd strongly suggest not changing what they entered. Change it to a display-only element with nice formatting if you want, but don't screw with their input.
Nah. Users are too stupid to fix their own inputs in many cases. Seen inputs with zero-width spaces that are invisible which fail validation. User doesn't understand why, complains. Enforcing a character set for certain kinds of inputs is a very good thing.
In 26 years of web dev, mostly as a frontend person, I've only seen zero width spaces in three situations
- pasting from Word
- QA testers being through
- devs pranking each other
The third one is by far the most common. Word is much better these days and I've not seen that happen in a long time. I wish I saw QA test this stuff more often. The idea that it's common enough that you'd break your UX to handle it baffling to me.
I'll be one of those guys. I see the invisible whitespace from pasting ALL the time. I've literally dealt with user complaints caused by it three times in the last two weeks! (Usually customer issues don't make it to me unless our support team can't figure it out or suspects a bug)
To be fair, it's not usually that frequent. Just a funny coincidence that I've JUST dealt with it more recently.
"Break your UX" is a vast exaggeration. I'm not talking about phone number fields, to be clear. I'm talking about like numeric amounts, with maybe a negative or decimal point. It's literally just [0-9\.-] but that still requires JS to limit inputs to that.
It doesn't prevent the bad input, it only validates it on submission. Therefore it's on the user to fix it, and if it's from a zero-width space, it's literally invisible. Non-technical users will have no idea what to look for to fix it (i.e. use your arrow keys cursor to see at which character the arrow key doesn't shift visually, and there's the ZWSP). It happens way too often.
The problem here is that sometimes users and copy pasting from another document and that comes in arbitrary formatting, not the one enforced by the input element.
For example phone numbers can be a string of digits, or multiple strings separated by spaces or hyphens or with parts enclosed by () etc
It's a more pleasant UX to let them paste anything, then edit it inside the input, validate and submit.
> For example phone numbers can be a string of digits, or multiple strings separated by spaces or hyphens or with parts enclosed by () etc
>
> It's a more pleasant UX to let them paste anything, then edit it inside the input, validate and submit.
How is that more pleasant than a textbox which automatically removes the extra characters?
What if I copy something but accidentally get another couple words one of which is a number. For example copying from a chat app and get the date with the message. Then my "Sep 24th 416-555-1234" input which, would have been very easy to fix, becomes 244-165-5512 34. It will take me a few seconds to realize what has happened, identify where the intended phone number starts and remove the accidentally pasted digits.
The nice thing about the native input is that it is very simple, predictable and flexible. It may be easier to make a better UX on the happy cases but it is very difficult to not add some suboptimal and confusing UX on the less happy cases. Often times it is best just to keep it simple so that the user can easily complete their task rather than adding some "magic" which may backfire and confuse users.
It is surprisingly often that I need to open a text-editor or clipboard-editor to format values before pasting them into apps or websites because they have broken an input field by trying to be magic and failing to consider anything but the happy cases and maybe one or two bad paths.
The exact same problem applies. If I copy "Sep 24 $2412.45" out of a message and you quickly "clean" it to 242 412.45 I may not notice and even if I do it will take a second for me to realize what happened and clean up the value to be the intended amount. If I see the original text in the field it is much more obvious what happened and quicker for me to understand what I need to do to fix it.
> FWIW if you're copying text on Android, you can tap the clipboard popup to edit the clipboard item before pasting it elsewhere.
I never noticed that after 13 years of Android. I checked that now and I could not find a way to do it. Samsung's keyboard has a way to look at the clipboard but I could not edit them. Swiftkey does not. Maybe Google's keyboard? It's not on my phone. I looked at a couple of videos but they don't look anywhere like my phone. Not a feature to invest much time on it. If I have to edit the clipboard and I can't do it where I want to paste it, I open an editor and paste it there.
I'm using stock Android, Pixel 8 Pro. Highlight text then tap "Copy". See a toast in the bottom left. Tap on it (not the X) and a little text editor applet opens up. Here you can edit the text and save it, updating the value in the clipboard. Then using Gboard, it has clipboard history so you can see and paste the specific recent item from the past hour that you want. (Unfortunately it can't be edited after initially copying although you can long press them in the Gboard menu to pin for longer or delete them).
In most cases when you are accepting a numeric value it is best to just strip anything that isn't 0-9 then run validation on just the digits. There are some exceptions like phone numbers which may need + prefixes and similar but you can adjust these rules.
What I have found to work well is when the user unfocuses the input field or on submit strip everything but expected values then validate. If you want you can format the value at this time too (and the formatting won't interfere with text input).
If you want to get really fancy you can strip and format as they type and be careful to keep the formatting "virtual" such that the user is only editing the raw digits but this is very tricky to get right on all platforms and support all expected native editing UX. But even in the best cases this can have bad edge cases. For example the user pastes some text but it happens to have multiple numbers in it, if you eagerly strip and format what is left for the user will be these two numbers mushed together with misplaced separators or similar. If you let them paste, remove the unintended stuff, then format on blur this just works and is understandable.
Or, you know, prevent invalid characters from the get-go. Same thing as validation, but done up-front. (But as I said elsewhere, I'm not talking about phone numbers, I'm talking about amounts)
I would like to allow people to copy-and-paste text in, and then edit it. That could be a longer text that has the amount in it (but also some unrelated numbers).
Because this often makes the input feel broken to the user.
Instead of asserting that "users are too stupid" as you have done earlier, perhaps programmers should be less stupid and write more permissive parsers.
I'm not using "stupid" in the derogatory sense. I'm using it as a recognition of the skill/knowledge gap between technical and non-technical users.
To clarify, we get _asked_ by our users to implement fields that limit input to help them avoid mistakes. Our QA and UX teams agree. This isn't a unilateral engineering decision.
Yes, you want to provide guidance, but without getting in the way.
That's why I was suggesting letting the user paste in these 'wrong' characters, but offering help in removing them.
Of course, that's a trade-off. And it's more annoying to design and implement than just forbidding those characters from entering the input field in the first place.
I'm not being user hostile. I'm being cognizant that the skill levels of users is extremely wide, and to best serve everyone from a UX standpoint, it's best to limit the characters accepted in the input. It protects the user, helps them avoid mistakes.
From reading your comments, you're extremely user hostile and I hope to not come across anything you work on because they are the very definition of antipatterns
Please read my other comments. I'm not using "stupid" in the derogatory sense. I'm using it as a recognition of the skill/knowledge gap between technical and non-technical users.
> what's crazy is both of those still don't disallow non-numeric input
Which is really nice for copy pasting. For example, I have a number with spaces in it, and when I paste I get nothing or only until the first space because someone decided I'm not allowed to have non-numericals in the input field at anytime.
Spinners always puzzled me, to be honest. There is obviously a need for a compact numeric input control that both displays the exact value and allows rough changes using the mouse. Witness knobs in DAWs—which don’t actually work the way you’d expect from their appearance, you’re supposed to grab and then drag in a linear fashion, possibly ending outside the knob’s screen bounds. Or consider the weird input thing Darktable uses—which at least doesn’t mislead you with false skeuomorphism, but takes a bit to figure out. Then there are the inputs used for color grading in DaVinci Resolve. And so on. And all of them are nonobvious. Spinners are obvious, but they are also needlessly fiddly to use with the mouse, and neither do they provide the at-a-glance readability of knobs et al.
I feel like humanity just hasn’t solved compact numeric inputs yet.
> Spinners are obvious, but they are also needlessly fiddly to use with the mouse
I think that a quick improvement would be to let the mouse wheel "spin" the number up/down when the input element is focused.
An even better improvement would be having the `<input type='range'>` element actually display the value as it changed, and allow the user to set that value directly (say, by typing it in).
Right now, range is useless because the user cannot tell what is selected. The developer has to add in extra JS magic to let the user set range to an exact value, or to show the user the value they have chosen.
If `range` is improved in this way, then spinners are redundant and can be ignored.
> I think that a quick improvement would be to let the mouse wheel "spin" the number up/down when the input element is focused.
Firefox did that for number inputs for a long time, until very recently. They switched it off in Firefox 130 because people kept inadvertently changing values in forms while scrolling through them [0]. Personally, I've set the about:config option to reenable it since I've found it useful in certain interfaces, though I can't imagine it's much longer for this world.
Isn't this same issue already solved for other scrollable elements? Scroll should only affect the individual element if the mouse was over that element when you started scrolling.
I guess the room for unwanted consequences is a bit bigger when the scrolling controlls the value instead of just the viewport.
That is how it worked, but people still found it problematic. E.g., from one of the comments on the issue:
> In step (3) here, if you do several mousewheel-spins while also subtly moving the mouse (just from placing your hand on it), it's quite easy/possible for the first spin to inadvertently change the value that you just entered (since step 1 had left the cursor hovering the input field, so that's where it starts), and then for the subsequent mousewheel-spins to successfully scroll the page. This can mean you change the number you just entered without noticing (and also without it being "in the middle of an existing scroll action", hence my note that this suggested mitigation wouldn't necessarily help).
The cause being that people don't look at where their cursor is before they start scrolling, and don't look at the value since they've finished entering it.
That's almost correct. I generally agree with hover == focus as a Window Manager level thing, but for document inputs within an application I still prefer required user interaction to set the focus location. E.G. a click, a tab, just move the line forward.
The correct context model is to not select an element for scrolling until it has been made the active element, and that UI element SHOULD have some sort of embellishment to make it obvious that's the focus.
> Browsers automatically provide validation to ensure that only text that matches the standard format for Internet email addresses is entered into the input box. Browsers use an algorithm equivalent to the following regular expression:
It's not the fact that software engineering is broken saddens me as much as the extent.
Email is older than absolute majority of active developers and yet, it seems, simple knowledge like "what is email address" remains such an arcane knowledge that you are being looked at weird when present something a tiny little bit more correct than the status quo.
Where else can we assume that the common knowledge is flat out wrong?
Anything you can send an email to that is received, as far as I am concerned. I have my own domain, so why ahould I be forced to add an arbitrarily long string to it to be able to receive the mail? Or exclude <site>@myDomain.com from being input on <site>?
Or the worst of the worst: Disallow all but a few domains for emails.
At this point, not validating it cient side at all is IMO the correct approach, and instead send a verification email.
> Anything you can send an email to that is received, as far as I am concerned.
100% this.
The only acceptable hard validation is to check whether there is an @ between some characters. something like `.@.` in regex.
It makes sense to do sanity checking (soft validation) on client side. There is 99.9% chance that `muppet@gmial.com` is wrong, outright rejecting that is wrong, though.
This is particularly annoying on mobile since on-screen keyboards won't adjust to an email input layout and autocorrect will screw up basically any email address as soon as a "." character triggers autocomplete to commit it's guess.
I found this very extended with "date" input. It seems that every single frontend library has its own date widgets, and lots of them look awful in small screens. You have to add a JS and CSS just for that widget, some depending on jQuery. True, some of them are very configurable, but with the tiny cost of "<input type='date'>" you have a widget that looks decent and native everywhere, probably cover your needs, and you can forget about it forever (e.g. no updates, no CDN).
A lot of those date and time pickers will fail WCAG testing as well.
In most cases, GDS now use just 3 text fields for day, month and year, but recommend pickers for dates close to today's date e.g. for booking an appointment, because a picker is easier if you don't know the exact date without reference to a calendar.
Sadly they don't currently have a recommended picker, but there's a useful discussion of what has been tried here:
The native date input is terrible. Not the actual native control, which is usually okay, but the field itself. You can't even format the date! That's the number one reason I always use some datepicker library in combination with a regular text input.
IMO, you (the web developer) should not be formatting the date shown in the input widget. The input should be shown to the client following the system settings, so a US browser would show MMDDYYYY, while an European browser would show DDMMYYYY. And the field is correctly (IMO) normalizing all of them to ISO-8601 (YYYYMMDD) before sending it back.
And I have this opinion because I had to deal before with format configuration and normalization before saving to the database, when using a JS library. Now I just drop a "input type=date", and I know I'm going to get the ISO formatted date at the backend.
If my entire application used YYYY-MM-DD everywhere, it can be very confusing for users when the input suddenly uses something else. And often the locale or system settings are incorrect anyway. When I an working on a Dutch site with a Dutch locale and lang settings, then dates should be shown according to the Dutch locale, not according to whatever system of browser locale there is.
I always keep my OS and browser in English (makes searching for error messages sooo much easier) but I hate that I need to change my OS settings just to get Firefox to display the date in a proper way on some site.
My apps usually deal with non-technical people (thus ISO in the browser input is out of the question), and sometimes spread at least between Europe and US (so people would enter MMDDYYYY and DDMMYYYY, and keep in mind that some dates work validate for both formats, namely every 12 first days for each month). Behind the scenes everything is ISO and UTC, but everyone gets their preferred format in the frontend.
I'm not getting your Dutch example. If I'm in the US and use MMDDYYYY almost always, and want to access some Dutch site, what date format would you show me in the input form? DDMMYYYY only because the backend is hosted in Europe? You will get wrong dates (e.g. 11/1/2024 for the first day of november, your system will store 11th of january) for at least half the US visitors.
Or maybe you are talking about "dates displayed" instead of "dates input", which is a different problem?
To be honest I would expect dates on a Dutch site to be shown in dutch format, just like I expect dates on American sites to be formatted in the US way.
Lets clarify a bit here. There are two different problems:
- Date display. I prefer to show it in the browser preferred format, but in the end what you say is also OK. It's a very minor issue.
- Date input. I would never force a format to the user, it there is any chance people from different locales can access the web. The correct way, IMO, is "input in the preferred browser format, send data as ISO". Any other combination would cause errors, e.g. "input in the preferred browser format, send data in that format" and you'll get wrong dates in the backend, or need to do a lot of gymnastics to avoid them. "input in server locale, send data in any format", and you'll get wrong dates from people used to any format that is not your server locale that happens to validate in multiple locales. "input in ISO, data send as ISO", you'll get users upset because "YYYY-MM-DD is stupid, use MY locale instead".
I'm trying to picture a room full of <s>people</s> developers agreeing letters are numbers too!
Lets give the little people a slider but lets call it a range!
I really feel like they are trolling.
You start with a neat database table then you engage in an endless struggle trying to allow the user to edit a single row of it. It really feels like you are not suppose to do it. As if it was intended to be as annoying as possible.
I had to recently make sure that we do not use any of the more complex input elements, because we need to drive them from on-screen keyboard that for various reasons is also implemented in-page.
And that means it's barely doable with normal inputs, the special ones support even less events.
> because we need to drive them from on-screen keyboard that for various reasons is also implemented in-page
There's your problem right there. Can you expand on the reasons? It seems like very bad practice for a website to provide it's own "keyboard" instead of using the system keyboard.
This is for a closed system that unfortunately sometimes is supposed to be available outside[1] - a touch screen panel UI for (big[2]) embedded system.
It's hard to impossible to properly guide OS outside the browser regarding what keyboard we want at different points in time unless we end up also implementing custom keyboard plus some way to talk with it from JS. Previously we used a Chromium extension that could bypass some of the issues because it had privileged access and thus could send "secure" events.
EDIT: For some extra context - for reasons of ease of use, we want the keyboard of appropriate type (numeric, qwerty, other specialized layouts) to show in position related to actual input field, not take entire lower part of the screen like typical on-screen keyboards. For dealing with possible edge cases or otherwise making it more accessible, we also provide for the keyboard to be draggable by user.
[1] Sometimes it's accessed externally instead of in-person, for various reasons this means we have both the ability to open the web interface and use VNC.
[2] By big I mean we have a complete PC running Linux there, with intel CPU/GPU and an SSD
Isn't this use case already solved by phone browsers? Layouts are controlled via the inputmode attribute. Positioning the keyboard should be something solved by the host environment.
2. "Solved by host environment" in practice means "worse user experience" as pretty much all of them simply use lower portion of the screen.
In comparison, the current draggable on screen keyboard I spent significant amount of time getting working allows the worker to drag the keyboard around if it overlaps a piece of information they need, as well as takes comparatively little space on screen enabling workers to better see what they are manipulating.
They could improve user experience everywhere if browser vendors wanted. E.g. why doesn't my (desktop) browser auto-complete recently-visited / bookmarked URLs when it sees type=url?
My product just failed an accessibility audit because we are using native HTML form validation and the official recommendation was to implement our own validation layer.
EDIT: which I agree with.
Native HTML validation has many flaws and visual customization is not my biggest concern to be honest (but it's the nail in the coffin).
E.g.:
- It's impossible to show multiple errors at once per field unless you concat strings ("You need a number. You need a symbol. Must be >10 chars.")
This is both bad UX and bad for accessibility (you cannot navigate concatenated strings on the accessibility tree). And this isn't even implementation dependent, it's the spec! You need multiple errors at once because playing whack-a-validation-error is not fun for users.
- It's browser-dependent which is bad because you can't control it and because the implementation is generally terrible (e.g. in Chrome it shows a popup on focus, which is not very accessible by itself because (1) it's a popup (2) that shows modally (3) and can't show all form errors at once).
Not using popups for important information is accessibility 101, but browsers cannot afford to do anything else without interfering with the actual document.
- You still need custom validation for form-wide errors (like errors that don't belong to a particular field, "Fields A and B are incompatible") so you might as well have a consistent validation story.
- It requires you to have hidden inputs to be consistent (-ish) if you have some custom input that doesn't fit any of the native input types -- this breaks accessibility too and fixing it is as hard as having your own accessibility-friendly validation story.
- The custom validity API is imperative and cumbersome to use. Not using custom validity is almost never an option unless you want terrible messages ("This field is invalid")
Thanks, that's quite interesting and insightful! Thank you for sharing
The fact that something provided by the browser can fail accessibility requirements is definitely ironic. We're always taught that the motivation to "use the platform" and "follow semantics and semantic elements" is partly to satisfy the accessibility concerns.
I still think it's worth to leverage the native validation mechanisms.
* You don't have to use the native validity tooltips for the error messages. You can read directly from the input's ValidityState (input.validity) and render the message however you like and show multiple errors if you need to
* The browser can improve and you will benefit from using a standardized approach
The fact that "not using popups" supposedly breaks a11y sounds weird, though. But if you need to respond to an audit then this is the way you can go.
> Errors that do not belong to a particular field
These are indeed interesting! There are techniques to handle those, too. In my project I have a "HiddenValidationInput" component that renders an invisible readonly input that serves the purpose of rendering a custom error that doesn't belong to any other field. It's in fact quite a pleasure to use because you can just conditionally render it.
> The custom validity API is imperative and cumbersome to use
Absolutely agree on this one, and handling this is exactly what my article is about. And I really hope that this part will improve in time, too
> You can read directly from the input's ValidityState (input.validity)
Feels like I don't gain much from that. Native validation is very limited and the few cases that it covers are super simple to implement already. Am I missing something?
I'd rather have a `validateSomething` which returns a discriminated union of error causes than using `pattern` and just getting a boolean.
> In my project I have a "HiddenValidationInput" component
Yeah, that's an accessibility issue (and the UX for the common user is terrible too for multiple reasons).
Interesting, because for my apps, I implement all those validations. The form wide validation are done on server. Basically I have a bunch of layers of validation that leverages everything. Chrome having a shoddy unaccessible design is Chrome problem, I would file a bug report.
That the browser implementations are generally terrible and wouldn't pass accessibility audits, so all browsers would have to change and then some time to pass for the fixed versions to be widespread.
We didn't discuss browser-specific issues in detail, but I edited some points in my original message that highlight some of the issues that I suspect make it a no-go for accessibility.
Seems to me that this says that the browsers have the accessibility problems and that's what should be fixed. Why does every website developer have to work around this while the browsers get a free pass?
If field validation is "standard HTML" and browsers can't do it in an accessible way, that's squarely a browser problem.
Because in reality browsers can't do much. The API and spec are broken as-is.
I'll quote my top-level comment:
> This is both bad UX and bad for accessibility (you cannot navigate concatenated strings on the accessibility tree). And this isn't even implementation dependent, it's the spec!
> Not using popups for important information is accessibility 101, but browsers cannot afford to do anything else without interfering with the actual document.
Plus it doesn't matter who's to blame: people with accessibility issues need access now.
> Why does every website developer have to work around this while the browsers get a free pass?
Because browser makers are merrily taking that free pass, whether we like it or not, and people who need accessibility allowances need them now, or better still quite some years ago, rather than at some future time after we've nagged the browsers into taking useful action.
It isn't entirely the browser people's fault, there are significant issues in the spec, as already discussed in these comments by people who know more about it than I, and that is part of why they feel justified in taking the free ride, but as some of them were involved in the original specs and they are in a position to propose alternatives & deliver PoC implementations, it is more their responsibility than they think. After all, Google in particular are more than willing & able to invent new specs¹ and throw implementations into production, when there might be marketshare, stalk^H^H^H^H^Hadvertising income, or protection money² on the line.
----
[1] and Apple deliberately break them, old or new, in a fit of pique!
[2] Nice app/extension you have there, it would be a shame if it started failing store inclusion reviews, or if APIs had breaking changes for our benefit underneath you.
In an all honest reply, is that the people that writes these specifications, live disconnected from the reality, they don't use the stuff they specify. That stuff works for very simple things, but then when your forms evolve you realise you will be better off just writing the whole thing yourself.
This. Doing relatively common things like cross-referencing from other fields ("did the user specify a country? If so, we can validate the postcode/zip code they just entered, but if not we'll have to wait until they pick a country") almost immediately require JS to handle, and as soon as you're using JS then it's all just easier to do in code than trying to mess around with validation properties.
Yep. This is great until you need a cross-browser date picker, at which point you need to implement a bunch of stuff yourself. It’s frustrating how primitive HTML forms are, after so many years.
What's hilarious is they do have UI for it in about:config "dom.forms.datetime.timepicker". It makes me so angry that it's not on by default. It works fine!
That you’re correctly using html forms won’t quickly lead to browser improvements.. so the result is that users will hate your forms.
Users/your customer might possibly even think that you’re to blame, and not $browserVendor.
I’ll go one further and say that the customers are absolutely justified to blame the developer instead of the browser. If a developer knowingly chooses a built-in form control whose common implementations are bad for their users, how are they not at fault for the resulting experience?
“This site only uses functionality provided by the HTML spec” is not a useful goal in and of itself. Using the right tool for the job, which might be JavaScript, is always more important.
The `required` attribute, which this article is about, is an HTML5 thing and first appeared in browsers in 2010-2011. So sure, not brand spanking new, but the web was already used to write modern apps. There's no good reason for the validation features to be so shabby.
Even 'required' doesn't work properly. Browsers do very odd and inconsistent things when your required field is hidden when submitting. Like in a basic tabbed or multi-step form.
If you have a checkbox with a label, please a "for" attribute to the label so I can disable/enable the checkbox by clicking the label. This is one of my biggest pet peeves, maybe its just me.
I was thinking that it's so weird to talk about using standard HTML validation and then everything is shown with React? If we want to teach people how standard works, we can't assume React as the default.
I addressed this elsewhere in the comment section, but there's not much "react" going on in the article. I do think that JSX is very expressive and the concern I cover mostly involves the declarative "component" model for writing UIs. It's not react-specific.
I believe you could probably do most of that with just css now too. Disabling the default pop up from showing up may be the only thing you need javascript to do.
I'm using Firefox on all of my mobile devices but I can't blame devs for ignoring FF for Android on this one. This is an API every other browser had working 10 years ago, it's on the Firefox team to sort out this mess. The less than a percent of users who don't see the error messages for controls marked in red isn't worth ignoring the standard for.
The more websites use this, the more pressure Mozilla will feel to fix their browser. This isn't something like WebMIDI or whatever API Chrome or Safari implemented before standardising, it's part of the original HTML5 spec.
Firefox for Android has a smaller user base than Samsung Internet and Opera. It's 0.5%. It's a waste of time working on supporting it. Especially considering how little time people put into making sure their sites work for people using accessibility software. I don't think it's worth mentioning in these issues unless you're also ready to talk about UC Browser.
Is that somewhat biased? - I assume the number of people using Firefox has a quite big overlap with people using ad&tracking blockers, which block many statistic sites. (Website operators may log user agent which will be somewhat accurate still)
This is always something I question whenever the analytics numbers come out. I know my adblocker blocks GA, so I'm not going to be included in any GA statistics.
Every time I've asked a marketing person about this they get hand-wavy about "it all comes out in the wash". But meanwhile they say things like "our analytics show that our market is mostly older and non-tech-savvy people". I'm not sure that the analytics numbers do actually show that. I think that's just the demographic that you can see.
As a daily Firefox on Android user, not catching up on standards is what hurts the most. Most painfully to me, all the WebGL stuff like [1] and some minor annoyances like [2]. Still, having uBlock origin among other extensions is a killer feature.
It's much worse than "doesn't work": the validations work, they just don't show any error. It would be okay if validations just weren't implemented, but this is just absolutely fucked. I discovered this years ago after a long and painful debug session, and I'm quite sure I wasn't the first or last to go through that.
I just realized this having switched to FF on Android fairly recently. Working on an app and saw literally nothing when trying to submit an empty required field. Couldn't imagine what I was missing until I searched. I was stunned. No issue with rolling your own validation but this should work!
You gotta be careful about going overboard with it.
Recently I was trying to get a refund on Groupon because the company I'd bought a Groupon for was under new management that refused to honor my groupon.
The form had a stipulation "minimum of 15 words". Try as I might, I could not get the form to pass validate until I inspected the HTML.
<input pattern="^(\b\w+\b\s*){15,}$" required>
\w - word characters
\b - word boundaries
\s - white
Literally zero allowance for any sort of punctuation.
I don't think this is particularly pertinent to HTML validation. This is true of any type of validation. The same rule could have been applied on the server, and then you would have had no hope.
That's actually a good argument for the point I was trying to make. Existing validity attributes such as "pattern" are cool, but not enough.
E.g. the "repeat password" example is actually achievable without "setCustomValidity" by using the "pattern" attribute. For that, you would have to dynamically construct a RegEx out of the value from the first input. I didn't want to make the article too long by comparing the solutions, but the point is, with the "customValidity" you see how much more eloquent and easier to read the validation is.
So a nicer API here makes all the difference
The "15 word minimum" constraint would look so much nicer as "value.split(/\s+/).length >= 15".
There’s a reason it’s heavily underused. So many frameworks and libraries provide robust, style-able validation capabilities, some with very sophisticated and extendable functionality. Don’t torture yourself if you don’t have to.
You also have to implement your own validation on the backend anyway. There's always going to be someone trying to fiddle around with your form, either using some weird browser, curl, or some other tool that doesn't have the same form validation built in. You're not going to trust that the client actually did the validation, or did it correctly, so the backend still needs to be able to validate input and show the form, with validation errors, on all fields.
Frontend validation is only there to be helpful for the user, but if you can style it, or trigger it from the backend on submit, you have to implement your own styling anyway.
We try to use browsers standard features whenever possible. Despite looking into using the built-in validation, it's never been worthwhile. Too many gotchas, and we end up using a library to be able to easily support more complex checks anyway.
Furthermore, using a library opens up, in some cases, the possibility of sharing some of the validation code between front and backend.
In particular this article seems to work around one of the issues with `useLayoutEffect`. Not something that should be done lightly.
One of the things I dislike about HTML form validation is it starts running from page load. So if e.g. you tie error state formatting to it, the form loads up with a bunch of errors which may be intimidating to the user.
There is the :user-invalid pseudo-class that lets you avoid this to some extent, but it has some inflexibility that may mean it isn't enough, depending on your use case.
There ought to just be a property named something like `defer-validation` that does the right thing. But I'm sure I'm not the first person to suggest it, there's presumably some logistical or technical difficulty.
If I'm making a wish list I'd also like to point a property at a handler function that accepted a `string` and returned a `string | null` (or at least a `nonempty string | empty string`) rather than using an onchange handler, but it is what it is.
A bit perplexed by your comment. That wasn't a main reason people started using javascript.
I even remember when people started evangelizing client-side validation in the mid-2000s. Javascript was already a normal tool used in web apps by then, and most web developers would regularly be adding javascript to their apps.
Back then it was a bit of a pita as you had all sorts of gotchas with javascript memory leaks by registering change events on controls. I can't even remember the term now, but you could basically have a circular reference between a closure and a control and so it wouldn't cleanup properly.
Also, modern developers probably can't even begin to imagine how slow javascript was on IE6. A loop of a few 100 iterations could bring it to an unresponsive halt.
Correct, I meant that client-side validation driven by JS became popular because of UX issues when using pure HTML. There have always been plenty of other reasons to use JS with forms besides validation. But it’s notable because forms and form validation are such common building blocks that if people feel the need to use JS there, it kind of infects everything else around it. IMO, being able to build high quality form experiences without JS is critical to reducing bloat on the web.
JS form validation quite significantly predates HTML form validation. The alternative was server side form validation, for the longest time. HTML form validation was meant to standardise and reduce the need for JS validation, but for UX reasons it hasn't really managed that. And that you'll need JS anyway if you're doing validation specific to your business logic that doesn't fit into the set of rules HTML validation has.
I've never understood why this was chosen as the default experience. Most users don't enjoy having every form element yelling at them for actions they haven't even had a chance to take! You can script around this, but at that point the feature isn't doing much. I'd argue this is the biggest reason you don't see more widespread adoption.
True, but vast majority of websites don't do the right thing. So password managers need to manage a database of form input overrides. I worked at a small company building a password manager and it was a bit of a nightmare, we had to allocate support staff resources to handling reports of website incompatibilities.
I worked for a small company that did. The idea was the password manager lived only on your phone, and you'd connect it to your computer in various ways. Notably including our own hardware, USB nub that connected to the phone app via Bluetooth and acted as a keyboard for the device and the app would instruct it to do the keystrokes to enter your saved credentials. Also a browser extension that the app would connect to over websockets (through our relay servers, DH key exchange to encrypt the connection end to end) and the extension would request the app to send down the credentials on demand. Also we were a very early adopter/implementor of FIDO U2F (security keys). The product kinda hinged on the paranoia of the userbase (which I never aligned with, I trust 1Password and cloud sync'd encrypted vaults for example) so it never really took off. It wasn't "my" product, but I worked on it for a few years, right out of school.
It does not translate with the application but with browsers settings, it doesn’t style or fit any design. It looks differently on different browsers and it is really hard to explain to stakeholders “this is from browser I don’t have control over it”.
It does suck, but I think not for the reasons you mention.
I truly believe a nicer API would motivate developers to use it, and if native validations satisfy the product requirement, their styling does become a lesser concern.
But surely styling is still important, but another great topic to write about is the fact that you actually can opt-in to showing native validity errors in a custom way!
And your application should be looking at ... the browser settings.
I could see a case, if a user decides to somehow make a single website use a different language than the others. I guess it would be a browser's job to have specific languages for specific websites.
It works for presenting or selecting initial language. Even that is debatable because some big players don't even care about that and present language based on location.
Explaining to people they should go and change their browser settings is major hassle.
Automatic language selection based on location is an anti-pattern. If I am traveling, I don't suddenly switch my brain to another language. Whoever writes websites like that doesn't properly think about it.
These validation at input can be super annoying when you're copy-pasting your strings from other sources, and want to edit them in textbox in-place. Especially if you're on your phone.
I've be frustrated by this on numerous websites, a lot.
but also cross-system context switches, amateur RegExp, escape character (ab|mis)use, etc. can make "user-input" propagate farther than any one team's boundaries.
assertions/test coverage/fuzzing at every boundary so user-input taint analysis can't fail is a requirement for a system that passes user data around more than one time or tech stack.
> True, but if there's a communication bug between UX and back-end teams, that can escalate into a false sense of security and then an exploit.
How so? The backend ALWAYS validates. No communication necessary, whether or not the frontend also validates doesn't matter to the backend. Frontend validation is to improve user experience, nothing more.
Exactly. Sometimes in a system so big compartmentalization is required yet meta-communication is inhibited, that comfort-ability can lead to false asserts / assumptions.
"We always validate - no need for _me_ to do it" type bystander effect / diffusion of responsibility.
You were being downvoted here, but I think you make a great point.
The problem with having separate client-side and server-side validation logic is that you (generally) want the rules to be the same, but you end up needing to write them twice, usually in completely different technologies. I have seen many, many cases where the client-side validation and server-side validation got out of sync, and then just like you put it, obscure bugs or security exploits can arise from this.
In general, I think client-side validation should really only be used for the basics, often with respect to type (e.g. the email/URL examples given) and just basic "required" (non-empty) fields. Anything more complicated than that should be done solely server-side in my opinion - e.g. I wouldn't use setCustomValidity with a complex set of client-side rules. What I think is important, though, is to ensure that if the server validation fails that the error message that comes back is not just a single "Bad input!" message, but errors can be keyed by field to ensure you can display field-specific error messages and error highlighting.
Another option I considered back in the day when my backend was on NodeJS is to have the server return the text for a JavaScript validation function before the form itself is actually rendered. This, this function can be run client-side for immediate feedback when the user submits the form, but it's also the exact same logic that is run on the server when the form values are received.
This was one of the biggest "oh shit" moments I had when learning Remix: I could reuse the same validators across front and backend and they could even be right there in the same file.
It's a UX feature, absolutely, but you can't trigger the browsers validators from the backend, so you'd need to implement your own styling anyway, probably even add a bit more information than the browser can natively handle.
simply adding required is all you need.Not required=true The omission is equal to required=false. No one really write required=true, they just add the attribute `required` only by its self. This is one of the odd quarks about html attrs
> The strings "true" and "false" are invalid values. To set the attribute to false, the attribute should be omitted altogether. Though modern browsers treat any string value as true, you should not rely on that behavior.
in other words required=false may still end up making the field required. FYI.
They've used `required={true}`, not `required="true"`, which is JSX, not HTML. The one with curlies isn't even valid HTML. In the old HTML spec, the correct value, if you wanted to set a value, was to set `required="required"`, but these days the spec is looser since it tries to conform to the web, not the other way around.
Even in jsx its not required to add a boolean value. Unless you are passing in a var as a prop in which case sure. But that didn't look like it was the case in these examples.
> Even in jsx its not required to add a boolean value
Absolutely true! But I like to do it because I personally think it reads more nicely and is more explicit and that's what I do in all my projects. But it is indeed a matter of taste and I have nothing against code that follows the convention to omit the "true" value.
You usually create debounced inputs for that. This is similar to the autosuggest and typeahead inputs and comboboxes: sending requests to the server in response to an input change isn't something unusual
It’s a major security/privacy issue, you don’t want to tell world+dog all registered users, especially since that’s typically an email address.
Huge, huge, massive “no no”.
Likewise you still have to do sever side validation as any client side code can be modified, or you can just send payloads directly to the server. IMHO client side form validation is dangerous as it gives a false sense of security.
It's not actually all that bad, if you do it asynchronously and in batches (as much as possible).
The total amount of traffic in both direction is pretty small, and the logic is simple, especially compared to lots of other things your server is typically doing.
I don't think the amount of traffic is necessarily the issue. You're validation could be fairly "expensive". Maybe you need to do a lookup in a legacy system, maybe you need to check multiple systems?
You'd probably have to wait until the user moves on to the next field, if there's more, but that's also a little silly, as you'd force the user to go back to a previous field.
Ya'll may want to checkout Valibot¹ or Zod² in conjunction with something like React Hook Forms³ or the more agnostic Tanstack Forms⁴. Really sweet form validation that's concise but as precise as you want it to be.
The problem with vanilla form validations are (1) they're so basic that it's table stakes for any library or framework in this space, even ChatGPT can do it well, (2) there's an enormous amount of other validation scenarios they don't cover, and (3) unless your validation is simple and doesn't require a validation library, now your logic is split between two places.
> there's an enormous amount of other validation scenarios they don't cover
Can you provide examples of those? Genuinely interested as I'm on a quest of creating a list of recipes that show that native form validation can be just as capable as custom validation libraries
And he loses his page state if there is an error. You have to do server-side validation regardless, but client-side validation can be a lot more pleasant for the user.
I used to think it doubled your workload to do both, but if you are using JS-free client-side validation, I think that the server can just return an HTTP error guilt-free for any invalid input that the browser will catch. It’s a pretty good compromise for format validation.
Using your browser's back navigation from the error page to the form should result in the values still being there unless you are doing something stupid with client-side rendering.
The best solution is to use HTMX (or similar) to hook into your server-side validation so that you only have validation code one place (on the server), but you don't have to wait for complete form submission before finding an error in a field.
I share the wish that there was more effort in the browser space to improve the built-in controls but I would also recommend that people thinking they can easily do better try some real usability and especially accessibility testing. One very nice trait of the standard APIs are that they’re very lightweight and people who build assistive tools like screen readers and Braille displays know about and support them.
It is so easy for developers to think they have something better after a simple NPM install, until they test it on a slow (i.e. median) phone or watch a blind person try to use their application and then spend weeks trying to improve things. Given how common web forms are it’d be really nice if we had an Interop-style competition focused on making the out of the box experience better for normal people both for the controls integrated in browsers and the myriad of JavaScript widgets.
It's also easily misused. Take the regular expression validator for passwords on the California DMV website, for example. The website states "Must include at least 4 alpha characters". But the validation pattern
^(?=(.*[a-zA-Z]){4,})(?=.*[0-9!#$%]).+$
requires that these characters appear consecutively.
Yep, and the .* means "0 or more of anything", so it's 4 or more groups that each end with a letter. They can be consecutive or not and a group can be a single letter but doesn't need to be - so whatever the failure was, it wasn't that (or the regex was typo'd here to be correct instead of what was actually on the site).
AFAIK customValidity is not an attribute and you can only use an imperative setCustomValidity API which is terrible cumbersome to use in a declarative framework like React.
> Also kinda anoying to have to duplicate this tho
Oh yes it is...
I once worked on a project where we had a tool that dynamically built client-side forms based on each customer's needs. After rolling it out for a big customer I discovered (after the original engineer responsible had already been fired for other reasons) that all of our dynamic forms had NO server side validation. none, zilch, nada.
We did have client side validation though, a good amount of it and nearly all of it was using native HTML features, and we had the whole form available server-side as well. So given that I was under a crunch, on form submission I loaded the HTML form server-side, manually iterated over all the elements and re-implemented the validation checks that were embedded in the HTML. Crazy times, but heck it was flexible!
I think it's a trilemma between security, convenience, and architectural sophistication (NB: I'm deliberately not saying complexity, because the code doesn't necessarily get more complex). It is usually physically possible to find a solution with equal security for a given level of convenience, but it will require an investment of creativity and possibly refactoring to realize. Both of those things are very expensive.
To take an extreme example, you could ensure that validation happens identically on both the back and front end by writing your own framework with that property. You could create a framework with no more security bugs than the next best alternative and while providing great UX. But writing a framework and shaking out the bugs is a huge lift.
So in practice you can't go all the way out on the third axis and it is approximately a dilemma. But if you're on the lookout for exceptions you may find an opportunity to cheat/curve bend (eg as suggested by other commenters, when using JS for the front and backend, you can use data modeling libraries like Zod to get most of the benefit for a fraction of the price of writing a framework).
> (NB: I'm deliberately not saying complexity, because the code doesn't necessarily get more complex)
the context was already lamenting the duplication of code, which in itself is a form of inconvenience, as you kinda admit; because generalizing it to "complexity" would be forgetting the possibility of adding resilience, and adding stuff doesn't necessarily mean anything gets more complex - just more entrophic, the stuff added may not be optimal.
> But writing a .... is a huge lift.
And also the only way to minimize the security risk; by rewriting/auditing/formalizing.
Ultimately the risk transformation is exponential; don't roll your own crypto, don't DIY authentication/authorization, don't risk your own inconvenience and assume security.
However the opposite, to use all the "agreed"-upon code, introduces a near similar surface area of risk, simply spread across more vectors. And because the vectors are spread, and the system is more complex, the dissolution of responsibility leads to the opportune laziest option - patching code together, trusting it works.
it would be wise to question why this convention is so normalized.
Just to put it on the record I am happy to acknowledge that duplication is an inconvenience as well as a security issue.
Your point about trusting conventional code is well made and important. Once I repeated that I shouldn't roll my own crypto. A cryptographer shrugged and told me, I mean, somebody has to write it, and that person might be you. (That person isn't me. I don't roll my own crypto. I do roll my own auth, because I'm comfortable with my understanding of authn/authz attacks. Use my software at your peril.)
Regarding complexity what I was thinking is that, after a lot of clever reflection, you might realize the proper solution is actually to take something away. To give an illustrative though not very realistic example, you might realize you didn't actually need a web backend at all and that the app can function local-only. Thereby solving your UX and security issues - client side validation is now completely acceptable. This architecture is simpler (less complex) in that the diagram contains fewer elements, but more sophisticated in that it contains more baked-in wisdom about how your normally web-based application can fulfill all it's requirements locally.
It's a bit disappointing that articles talking about HTML use JSX/React syntax instead of actual HTML (even more so not actually saying it). Example from the article:
I was once discussing a third-party integration with a React developer. The integration required that our app POST a couple of fields to the third-party's site. I found that the developer was struggling with the integration and they were asking me questions about it when I said something to them along the lines of "It's just an HTML form, with a couple of hidden inputs that when submitted make a POST request to this URL" they said to me "Yeah, well HTML is kinda old, it's not really used anymore"...
I'm sure I've said plenty of stupid things when I was green but I hope no one remembers them like I remember this one. It lives rent free in my head.
It's definitely true that many developers would benefit a lot from learning more about the basic HTML and the web platform. But I refuse to support the notion that this is somehow React's fault.
In my personal experience, react allowed me to rely more on the native web platform APIs, not less, than other frameworks (at the time that I switched to react)
> they said to me "Yeah, well HTML is kinda old, it's not really used anymore"...
> I'm sure I've said plenty of stupid things when I was green but I hope no one remembers them like I remember this one. It lives rent free in my head.
I'm doing gigging while my product is gaining traction. Last week, I received this verbatim rejection for a PR review at a client, who's oldest developer is 27:
"No, we don't want all the logic in the same place. You must split the logic up"
This is also one that will take up valuable space in my head till the end of time :-(
(PS. Yes, I split the logic so that it was evenly balanced in 3 different programming languages, instead of having the entire logic in C# alone)
The confusion in the article is so complete that I'm left wondering whether or not the author is aware that what they are writing is not, in fact, HTML.
Yeah, I am aware! Thank you for the concern :) I did address this in an adjacent comment, but I'll say again that I did contemplate over using JSX or not. Also yes, it may have been a good idea to add a disclaimer for the fact that the code I'm showing is JSX, but honestly there are so many other disclaimers I had in mind, all of them together would make the article twice as long and much more boring
It's exacerbated by the fact that the API they propose to make custom validation more ergonomic works for React, but would be much worse for plain Javascript and HTML.
The API I'm proposing would indeed bring much more benefit when used in a declarative way. That's the point I'm specifically trying to convey in the article.
I don't think I understand how it would be "worse" for plain JS and HTML though. Would love to hear your thoughts.
Actually, there is one possible concern. When HTML is returned by the server includes inputs with set "custom-validity" attributes and this HTML gets open by a browser with no javascript enabled, this would make the input "stuck" in an invalid state. This is an important edge case to consider but I do believe there is a resolution that would satisfy everyone
custom-validity={value.length ? "Fill out this field" : ""}
you can only use a static string for an attribute. So you'd need an event handler to set custom-validity from javascript when the input value changes, then a handler to setCustomValidity when custom-validity changes.
In other words, it's the same exact imperitive interface as setCustomValidity, except with an extra layer and the extra event handling has to be implmented along with it.
If I had a say, I'd go for an interface where custom-validation would take a javascript function name, and that function would take the value as input and optionally return a string with a validity message. Or it takes a javascript snippet like onclick, except one which returns an optional string value. Then again, there wouldn't be much difference from onchange.
Edit: to counterbalance some of the criticism, I think the article is very nicely written and formatted, and the interactive components are a good touch.
Sorry to disappoint, I did hesitate over this. But JSX is honestly very nice to read and also I didn't want to leave the impression that opting in to native form validation somehow forces you to not use javascript. And combination of javascript + html is, again, very nicely expressed with JSX.
The concepts are obviously easily translated to other component frameworks, but they also do apply to pure HTML and vanilla javascript.
The problem I am highlighting in the article is the absence of a declarative nature to the Custom Validity API, so I think it makes sense to use a declarative component approach in code examples
once you grasp the ergonomics of setCustomValidity() you can go crazy e.g. pass it a multitude of validation rules per input field.
unfortunately you’re sort of back to square one if you want to implement warnings (ie suboptimal inputs but still workable).
Edit: While grasping the ergonomics produces euphoria like solving a complex puzzle it’s also a hint at the pain un-initiated colleagues will feel when tasked with maintaining the code.
After reading all this, I think I'd still choose to do it away from the browser built in capabilities. I'd rather have full control over the process and the design than rely on the limited capabilities of browsers.
The browser is programmable; at this point they should stop getting clever about adding built-in functionality and instead just expose better ways to use the browser as a dumb UI toolkit.
Couldn't disagree more. Browser features can be much better at handling edge cases: disability, localisation, unusual devices, different input methods, weird screen sizes, etc... rather than hoping every developer does it right, building that in is more efficient and consistent. The common cases should be handled really well by browsers.
I couldn't disagree more; it might be good for disability but for localization, unusual devices, different input methods, weird screen sizes I have never seen that well executed by browsers. I almost always prefer a more full-featured alternative from a standard framework than whatever is lowest-common-denominator feature in a browser -- which also, depending on the browser, may or may not work the same or may or may not even exist.
The browser should provide low-level capabilities and let developers build the high-level functionality from it.
This article ultimately supports this by showing us exactly how half-baked this particular browser feature happens to be.
Browser functionality is typically (handwaving on exact numbers here) better than the worst 80% of sites, on par with the next 10%, and not as good as the top 10%. If you're putting in the effort to build a site in the top 10%, sure, you might not want to be "held back" by the browser. But the vast majority of sites would do better by using what's built into the browser.
And I would argue that the value the user receives from that top 10% of sites is not commensurate with the pain the user receives from the sites that think they're in the top 10% but aren't.
I don't know, what browser functionality are we talking about? Even this form validation has to be implemented; I don't think I've ever even seen it in the wild.
What percentage of websites are rolling their own functionality instead of using any one of the various library and framework that do this better?
There is no way that every single browser is going to implement some high-level feature in a satisfactory and future-proof. It's the wrong place to do it. Almost every attempt has been at least a partial failure. We might get something maybe a decade after it's in common use and then only the most basic version of that. And we get browser bloat for our troubles too.
I don't use the standard <select> controls in apps anymore because the build-in version is too simplistic. Don't even get me started on file uploads. Is everyone just supposed to be held-back by the minimum a browser can do everywhere? Why waste browser developers time building things that no one really wants to use.
As a user, I want common UI controls to look and behave the same way across all web sites. Ideally, across all applications on my OS, but that's also a lost cause. POLA[1]. I can accept if the developer wants to somehow extend an existing control to support something new, but it's so irritating when they just re-implement their own thing entirely because they think their ideas are better than the browser's. Multiply that mentality by every site out there, and you have the web as it is today: Everyone's site looks and feels inconsistent with every other site. And everyone ships a different 500 lines of code, each with different bugs, just to implement a drop-down box.
This is one of these things that sounds perfectly logical -- you want all UI components to look and behave the same across all applications and all websites -- but that is more theoretical than practical.
If you built an app that used just what the browser gives you and nothing more, you're leaving so much functionality on the floor. Having more expressive power often makes things simpler -- using more complex UI controls has allowed me to eliminate whole pages from my application. Users are happier and more productive.
Browser UI implementations can't do one thing that is vital: compete.
With this kind of take - why do we need different applications at all?
UX/UI is solved just use spreadsheet grid, you can do everything in spreadsheet and you will have exactly the same interface/way of doing things.
It is not a joke - I personally have like 80% of things in a spreadsheet (don't get me started what kind of spreadsheet abuse I have seen in my career). But I do understand that lots of stuff can be done much more efficiently with tailored controls and not everything is couple of drop-downs/text boxes.
Form validation, form elements, search... I've seen far too many sites try to reinvent a browser textarea or edit box, and fail at very basic things because they didn't handle anything they didn't personally think of. (Some common examples: some of the keyboard controls, or correct handling of scrolling when having enough text in the box to scroll, or the interaction between textarea scrolling and page scrolling...)
"satisfactory" is exactly what browsers tend to provide, with a side order of "no surprises". Designers reinvent browser functionality on a theory of "I don't want satisfactory, I want delightful and unique", and sometimes they succeed, but often they fail. As a user, I very rarely want "unique" when it comes to design.
You don't have to be held back by browsers, and you may well be able to do better, but many people who think they can do better end up doing worse.
I don't see what difference it makes whether you use some component built into the browser or some component built on top of the browser.
This article already starts out with how many ways you can screw up this built in browser feature. I bet you didn't even notice that the article examples were slightly broken. The "fix" shows the error when you press submit but doesn't highlight the field in red like if you backspaced it to empty. This is something my validation code does automatically and correctly.
> I don't see what difference it makes whether you use some component built into the browser or some component built on top of the browser.
And this is why you fail. When you use components built into the browser, everyone gets to benefit from the same years of experience and testing, so that edge cases you have never thought about are handled correctly. Websites that re-implement text boxes, history, scrolling, so many things, never get every detail right. They always break on cases the built-in equivalent would handle correctly. Sometimes weird edge-cases, but pretty often completely normal cases that don't appear on the developer's development machine.
> Websites that re-implement text boxes, history, scrolling, so many things, never get every detail right.
As browsers continue to give developers more low-level control, the less of a problem this is. Take one of your examples, history. This used to be a high-level feature implemented only by the browser and if you built an SPA your users either had a very bad experience or you had get "clever" with various tricks. Now, we have a nice history API.
You say that everyone benefits from the same years of experience and testing but at the same time they're limited to a single vendor. A single idea of how it should work. And a single implementation. Right now if I don't like how validation works/looks that is implemented in JavaScript, I can choose any number of alternatives or implement my own ideas.
The browser should help developers build the best possible solutions, it should not implement those solutions itself.
Browsers themselves have always had weird edge-cases and as a web developer I've always had to work around them (see this article). Sometimes even depending on the browser. The whole idea of an "SPA" was never even imagined by browser makers but developers made that happen.
> As browsers continue to give developers more low-level control, the less of a problem this is. Take one of your examples, history. This used to be a high-level feature implemented only by the browser and if you built an SPA your users either had a very bad experience or you had get "clever" with various tricks. Now, we have a nice history API.
Quite the opposite, in my experience! As browsers give developers more low-level control, they're more tempted to build half-assed replacements for built-in functionality.
The history API - it's good it exists, mainly because it gives SPA developers a way to solve one of the many intrinsic flaws in the SPA design. On the other hand, it's subject to ridiculous kinds of abuse (stuffing history to make it appear to users that the back button doesn't work), or getting out of sync (because web developers can't manage a stack) and making history unusable.
> The whole idea of an "SPA" was never even imagined by browser makers but developers made that happen.
Yes, with generally terrible results, which could have been avoided if browsers hadn't stagnated.
Really? This is like complaining about movies that use CGI -- you only complain when you can see it. When it's seamless, and often it is, you don't even notice or care.
Why stop at browser apps? All apps are terrible on all operating systems for all the same reasons.
> There is no way that every single browser is going to implement some high-level feature in a satisfactory and future-proof. It's the wrong place to do it.
There are far more websites than web browsers, and the turnover at the typical web agency is very high. There is no way that every single web dev is going to implement form validation in an accessible, secure, and his-webdev-replacement-proof way across all browsers and devices.
> This article ultimately supports this by showing us exactly how half-baked this particular browser feature happens to be.
In a way, yes. I do think there's a lot to improve from the browsers' side. I guess what I'm trying to say is that the "half baked" solution is also not quite as bad as "no solution" and 1) it can be improved, 2) it really can be used today if you know "how to cook it right"
You say "no solution" like form validation isn't one of the most common things that all web forms do today. Solutions exist. What I'm trying to say is instead of browser building adding high-level functionality like this they should simple continue to provide better ways for us to do it ourselves.
If you code for Windows or Mac OS, you get standard controls, and they do come with a lot of functionality, but ultimately it's still just building blocks for you to build your own functionality. That's what browsers should provide -- low level building blocks.
I totally understand this. Having DOM elements as an entry to some API isn't the best thing.
But firstly, I would consider what you're missing when you abandon native validation
* On submit, the first field that needs attention gets focused automatically
* Error messages for semantic attributes are localized automatically by the browser
* The native message tooltip are actually nice and their placement is handled by the browser. They aren't the best fit for any design system, but for many products they are way nicer than custom implementations.
* Possible styling using CSS pseudo-classes such an ":invalid" or ":user-invalid"
In the end, I do think that the developers would benefit from a more explicitly exposed API for this. Just like we got the "new URL()" constructor, but earlier we had to create an anchor node, fill in its "href" attribute and then read the anchor properties to get to the parts of the parsed URL.
> On submit, the first field that needs attention gets focused automatically
That is long solved.
> Error messages for semantic attributes are localized automatically by the browser
Assuming I want to use their error messages. I would prefer to provide my own, more detailed, error messages. Also what good is localized error messages in a non-localized form?
> The native message tooltip are actually nice and their placement is handled by the browser.
I definitely don't like the placement of the tooltip nor do I even like using tooltips for showing error messages. I much prefer permanently keeping the error message displayed under the field until the user edits the field.
I make some pretty large forms in my job with a lot of complex validation rules and non-technical users. We do validation way better than this.
Strongly disagree. There are so many places where the browser itself provides a reasonably good user interface, and web developers fuck it up - scroll hijacking and history manipulation being two of the biggest examples. I suspect that one of the reasons we ended up in JS-hell is that HTML and browser built-in functionality lagged behind user expectations for so long. If browsers had offered the equivalent of AJAX and DOM element replacement early on, heavy use of JS might never have caught on.
The browser only reluctantly accepts its role is an application UI platform. Every problem, including the ones you describe, come from the disconnect between what a browser is and what it is used for. The browser is always going to lag behind user expectations so that's why I think it's the last place we should put that functionality.
Adding more high-level UI functionality is really in conflict with the idea of browser as platform. Other features, like WASM, are pushing the browser the other way.
No it isn’t. It fucking sucks. Most everyone who learns HTML comes across the validation attributes, the god awful built in date pickers and other shit, and they throw it out in favour of custom built better UX implementations. Maybe in the past we would have been clueless because, well, they didn’t exist, but today they do. And they’re junk.
Call spade a spade. Don’t call it heavily underused.
It's extremely frustrating to me how reliably the anti-JS crowd on HN promotes this sort of "just use HTML / CSS" content. Having a general purpose programming is obviously beneficial for application development. There is no arguments to not use Javascript besides "some users (ie the people here on HN and virtually no one else) don't like to enable Javascript"
The last example is bad. You shouldn't scream at your users before they even had a chance to enter the required information so the second password field should not be marked red until the user either is done entering text there (onblur) or tries to submit the form.
That's totally true! Invalid states shouldn't be shown sooner than necessary
It's just that for the demos in the article it makes sense to show invalid states as soon as possible, but for a nicer UX in real apps you need to take into account "touched" and "submitted" states for the form and per input
For the demos I wanted the reader to know at a glance when our validation code takes effect and this obviously comes at a conflict with demoing a fully "real-world" behavior
This is one of my big gripes - when apps are trying to get ahead of me with validation or submission. When I'm entering a 2fa code, I don't need a big red error telling me that the code must be 5 digits before I'm even finished. Worse is when they immediately auto-submit upon entering the last digit, so if I made a mistake I can't backspace and correct it
That's nice, I'll use that next time. Although it always feels kind of bad to write client side validation code because you're going to have to do the same checks on the server side anyway.
I find it sad that so many frameworks leave the developer to duplicate server-side and client-side validation. There are obviously some things you can't reasonably validate on the client, but I'd like to see more automated ways to take backend constraints and check them on the client too.
Ideally constraints would also propagate from model definitions, so there could be a single source of truth for "what phone numbers do we accept". Some years back I tried to do this by parsing SQL table definitions, but never got far enough. Django does this, but it lacks pretty much any client-side validation support IIRC. (Or client-side anything, really...)
One of the compelling reasons to use Javascript-based frameworks like nextjs or remix.run is that you can reuse the same logic + types on the frontend and backend.
With Typescript, this is now my preferred way to build full-stack sites.
You could use something like json-schema to define constraints, and use json-schema validator libs on the front and back end to validate the form data against the schema.
You still need to handle the "what happens next" part on each side, but at least your validation rules are shared.
Why is that bad? Both have uses:
1. Client-side validation is for immediate feedback for the user.
2. Server-side validation is to block malicious actors
Built-in validation is pretty much the only reason I use forms.
Capturing input with frameworks is much simpler than pulling the values out of an event object, so I'd be okay with just using input and button elements.
Yet, that doesn't trigger the validation, so I end up wrapping it with a form element and using a submit button.
Do we finally have a standard solution for input masks ? 25 years ago I was struggling with this while my fellow desktop app devs had good input masks in their widgets, with easy to use pattern syntax. That would be embarrassing if not.
Guilty. Recently, when I was involved in a project that required a lot of attention to forms, I ended up overlooking the importance of basic simplicity. I regret it a bit. Thanks for sharing your perspective.
Are we seriously talking of HTML by using React examples? The article doesn't even explicitly aknowledge the fact that it is written within the context of react.
That's weird! Have you tried submitting the forms in the examples?
The custom messages are supposed to be shown in the native browser validation tooltips. The support for those is quite good! Even on mobile browsers
everything html offers more exotic than playing text leaves a bad taste in the month thanks to bad implementations.
yeah i can mark a field as numeric... but then when a phone renders the number only input all popular keyboards will also leave out every single clipboard buttons and helpers. url where you can also search if you type a phrase? too bad you just lost all typing correcting and prediction. it's lame and hopeless.
Last time I checked, web-browsers today still do not allow you to style the appearance of built-in HTML validation messages [1]; this wouldn't be so bad if Chrome (and Firefox) still conformed to their OS platform UI guidelines (i.e. so it looks system-generated, like how `title=""` tooltips used to be), instead Chrome uses this ugly yellow/orange icon color with black-text on a white background on a bubble with a fixed corner border radius - it clashes horribly with my current project's aesthetics.
[1] https://stackoverflow.com/questions/5328883/how-do-i-style-t...
Annoyingly, Chrome used to allow styling of validation-messages using vendor-prefixed pseudoelement selectors, but they removed that functionality and never brought it back; I'll chuck this on the same pile as other arbitrary annoyances like "can we have a native HTML combo-box please" and "why is <select multiple> still a horribly unusable ctrl+click box instead of a checkbox-list?".
I think the problem here is not as much with the absence of custom styling, because you can quite easily read the native "validity" state of the input and render it however you want.
The problem is that it's quite tricky to correctly subscribe to the changes of this validity state. There are indeed some validity events being dispatched, but unfortunately not always. Updating form state programmatically (such as calling "form.reset()" or setting input value via "input.value = '...'") doesn't trigger these events.
I think this is a separate good topic for investigations and for suggestions to the web platform
I think form validation should remain an app implemented part of a web form, rather than natively built into the browser.
The majority of the work in form validation is not in the validation of the data, but in the UX and interaction, display and update of state. There's no generic way to handle it, as it's very dependent on the app itself.
Keeping the browser smaller and cleaner, with less logic seems to be a better idea.
> Keeping the browser smaller and cleaner, with less logic seems to be a better idea
That idea died sometime around 15 years ago.
Chromium can probably be best-described as a kind-of user-mode OS at this point.
Checking if a string is a email (or at least looks like one), if it's a number, etc. is such a cheap processing, that setting up and tearing down a connection to the server to process it is a waste of resources. Client side validation has its uses, it's more responsive. The problem is that we want all these custom behaviors when it's actually some rudimentary data input validation.
I never really understood why people want to style stuff like this. I like how you can express yourself by using colors and layout and stuff like that. But at some point usability is more important than branding.
> usability is more important than branding.
Said no designer ever.
At work our design team came up with buttons that are 10x10 pixels on my screen. They are used to change pages (like on mobile, but this is a desktop program), the scroll events are ignored by design, so you either click the tiny buttons (which are slightly darker gray than the dark background) or you simulate a finger swipe via drag and drop with the mouse. Yes they designed a touch GUI for a desktop application.
>usability is more important than branding.
Any designer unwilling to say this, especially in the context of accessibility, should be outright fired. They are bad at their job.
Accessibility is a legally mandated requirement, not an afterthought
As a disabled person: "and yet"…
The place where I live is very good at pretending to do the right thing while doing absolutely nothing.
For example a touristic social account managed by some government entity posted some extra complicated wheelchair lift (that will inevitably break in 1 month at most) to show how disabled people are well integrated.
Meanwhile of course the real situation is that people on wheelchair can go almost nowhere at all. Newer public transport has even worse accessibility than before, elevators are mostly broken at all times and regular ramps are missing, doors regularly have super strong springs and a button to open them (which breaks all the time) when they should just have a much weaker spring instead.
Designers I've worked with are like the tourist social media account. Showing the one single place they made accessible and explicitly saying in meetings "we are good people, we care for disabled people"… and then hating me for pointing out the million other things that are not accessible.
plenty of designers say this, often company leadership is the one pushing them to style everything because everyone else does
Well the ones I've worked with couldn't care less.
Of course they love to show off how good they are to the poor disabled people, but that doesn't mean anything until some government reminds us that we are in breach of contract unless we make our GUI accessible.
Designers that come from a background of human machine interaction care and will say that. Designers who come from a background of art don't understand what is being talked about and so don't say anything - they tend to only ensure it works on their one devices which they have selected to be the best and ignore everything else.
The second group does make things that look nicer, but the first ensures it can be used. You really want both, but then you need to be careful about who wins when they disagree.
this seems like a very mean spirited take on accessibility?
I took from it that [the designers] are all mouth and no trousers – which is fairly common. But "the poor disabled people" seems patronising.
It is a patronising sentiment, but adjacent tonal cues suggest GGGP is offering it ironically, thus in ridicule of performative compliance.
On flipside, note that many regulations - in any human domain - are oriented to raise the level of the worst performing, not to support the efforts of the best or to optimise the middle.
Yes very patronising, a terrible attitude really. Which is why I criticise it.
Also I'm disabled myself, although not in a way that requires any adaptation to use a computer. But I of course notice these things a bit more than average; and I get to hear my elderly father's complaints about software that he can't use because of inaccessible design.
Of course a designer should be qualified and notice these things even more… but all they do is move buttons around and disable copy paste so that even fully abled people have a hard time using our software between versions.
I believe that was the commenter's point - that the designers described patronizingly virtue signal about their accessibility priorities, while their other decisions are troublesome.
>because everyone else does
Which everyone is only doing because it's an industry fad likely stemming from copycatting one or two instances where it was done for legitimate reasons.
And now we have llms who do the same as well
People want to style things to match their page, exactly because consistency is part of usability. Especially given the limitations of browser form validations, you will absolutely need your own validations in addition to any browser validations you use. But your own validations will look different from the browser-provided ones, at least on some browsers. Which will confuse users, hence decreasing usability.
And this also assumes that the browser validations are in any way usable to begin with. I would argue that they are not, and would require some sane styling to become usable in the first place.
News flash, every site doing things their own way is one of the core usability problems on the web. Designers love it. Users hate it.
I think consistency within an application is far more important than consistency across applications. And even if it were true that users hated the lack of consistency, it would fall on deaf ears: the web page developers can only influence their own page. They can't make Google or Mozilla or Apple come up with an actually usable error model, or any kind of good UI in general, so the only chance they have is to create a good UI for their own page, and hide the horrible defaults that each browser is reinventing.
But at some point usability is more important than branding.
I have never worked for any company or organisation that believed this. Most clients will send you their branding guidelines before sending their feature requests. If they get to choose between adding a new feature, improving usability or making sure everything follows the branding, they will choose the branding every time.
I think you're exaggerating here. I recognise the "branding is more important than usability" approach, but the OP specifically said "at some point". Have you ever worked for a company that forced a design decision knowing it would prevent anyone from using the product? I suspect not; there will always be some point.
The issue here is, at what point does usability take precedence. Does input validation fall under "branding" or "function"? IMO, an error modal is nothing to do with company branding, etc. — it's not even part of your document, it's the browser's responsibility. The browser can decide to do something completely different from showing a modal as far as its concerned, so you shouldn't make any assumptions. Your responsibility ends at declaring what valid data is.
It 1000% falls under branding. If you don't make errors consistent across browsers / platforms your support staff will politely but firmly burn your house down. There's no such thing as your responsibility ending and throwing your hands up when you're a company who has to do end-to-end support of your product.
Having as little native anything means you go from n sets of documentation to 1.
I think the disconnect here is in the interpretation of “more important.” Usability is more important than branding from the point of view of the victims of this kind of over-designed software, the end users. Because they are already being inflicted with a lot of branding, please at least give them conventional error messages.
Sure, but that's not how it works out in practice. It sure looks like everyone just rolls their own. Fun game: can you find any major website that uses the default validation?
This isn't an issue if everyone's an accessibly expert, otherwise we're sacrificing usability.
It looks out of place and broken and that creates user confusion. That is also a usability concern.
The standard HTML components are ancient and not very usable.
People like to complain about JavaScript on websites, but they often don't know in what a bleak world they would live.
I'm not sure about that, plenty of HackerNews users see its minimal and functional UI as a feature not a bug.
I wish there were more lightweight websites, none spring to mind other than HackerNews, SourceHut, and Pinboard.
I love that as well, I hate bloated sites just as the next one here.
But for any more complex form with dynamic content, JS is still inevitable. I guess for HN the input form at the bottom is enough. But Algolia uses a custom input component already.
On reflection my earlier comment was a little off the mark - all 3 of those sites use JavaScript, but minimally.
Zero JavaScript is rarely practical when there's meant to be interactivity of any kind. The issue isn't the language, but the appalling bloat that is now the norm on the web. And, course, bad design in its various forms.
True. But you can hide the default message and replace it with your own. You'll still benefit from the form validation.
There is no real benefit because the validation rules allowed there are often too limited for real use-cases anyway.
What do you mean there's no real benefit?
You give the same error messages based on whatever custom validation and control the output.
I've found it more annoying to mess with the browser validation API and using setCustomValidity/reportValidity etc. than to just use other validation libs. Ideally I'd use whatever library I want and they would call setCustomValidity for me though.
Using the related pseudo classes :valid, :invalid, :required, :optional is nice, but until last year you still had to do custom logic there because :user-valid/:user-invalid weren't implemented outside of Firefox. That created additional work and was annoying.
Do you have any examples?
Really? In my experience they easily cover the majority of cases - strings versus numbers, min and max length, upper and lower bounds to values, specifying what decimal level you’ll accept, you can even straight up provide a regex in the ‘pattern’ attribute.
You can even benefit from the default messages if you want that, grabbing `input.validationMessage` and rendering it as you wish.
For that matter, styling a select (single) isn't quite the walk in the park it should be.
[flagged]
I agree with you 100%; I hate it when websites think they’re being trendy by using undraggably-thin scrollbars or try to subvert the UA’s password-manager (banks…) or naively think they can block users right-clicking or copying images.
To clarify my position: I agree that UAs should be free to show validation messages as-appropriate for the user (I.e. those popover hints) but it is because Google decided to stylise them with a very specific aesthetic/design - as opposed to trying to fit-in to the host system - it clashes more. Now, I’m not suggesting that the UA popovers be fully CSS-able, but I would like to see some kind of coarse-grain control “hint” properties - just like we have with (non-WebKit-prefixed) scrollbars, <button>, most <input> types, and more besides. The issue here is that the validation popovers are almost uniquely exempt from styling compared to all other HTML platform features (the only other exception being `title=“”` tooltips, AFAIK).
By-comparison, this is kinda like the (still) half-broken support for dark-mode: if a page is dark-themed you (probably) don’t want nuclear-flash-white UA-provided popovers stinging your eyes because there’s no validation-popover background color hint. Similarly, supposing my website makes tasteful use of serif typefaces - but the input validation popovers will be in Chrome’s own Material-design sans-serif font, while OS/platform widgets will be in some third other font by-default but can generally still be set via CSS. If you’re on HN then you’re likely bothered by inappropriate mixing of serif and sans-serif typefaces, so I hope you can sympathise.
You're talking about millions of dollars of engineering resources to implement what not only doesn't matter, but is probably actually harmful in comparison to the status quo (however ugly that is). And that's just on the implementation side. Now consider the tens of thousands of downstream developers who are going to suck up more resources from their clients because browser developers offered them a new bauble and some knobs to tweak. All going towards something that shouldn't even exist.
The biggest, easiest to implement underutilization is:
"Using specific type attribute values, such as "email", "number", or "url""
These can significantly improve user experience on mobile by triggering the optimal keyboard.
I avoid the use of `type=number` and use `type=text inputmode=numeric` instead. It doesn't come with these arrow buttons which most users don't need anyway for entering numbers. Also the keyboard is better on iOS.
But what's crazy is both of those still don't disallow non-numeric input unless you use JS to reject keystrokes and intercept paste. HTML form validation is so incomplete and limited, every time I look at it I want to scream cause wtf there's so many just totally obvious things we need that don't exist by default and we need to reinvent the wheel. Native date and time inputs are still garbage so every UI framework has to build their own solution.
I used to write those fancy textboxes that reformatted your input as a phone number as you type, and intercept paste, and all that.
But then it turns out that you really do want a free-form text input. Let people paste text in, edit their text freely, then let it validate afterwards. When it validates, then reformat it.
For example, text boxes with length limits. These are awful. It messes with your ability to paste something in, then edit it down to the correct length.
Very much this. Live re-structuring runs afoul of tons of things you can't predict.
You can validate roughly anywhere, but at the absolute earliest, only re-format on blur. Never earlier. You have no idea what the user might be doing in the meantime.
And even then, I'd strongly suggest not changing what they entered. Change it to a display-only element with nice formatting if you want, but don't screw with their input.
Nah. Users are too stupid to fix their own inputs in many cases. Seen inputs with zero-width spaces that are invisible which fail validation. User doesn't understand why, complains. Enforcing a character set for certain kinds of inputs is a very good thing.
In 26 years of web dev, mostly as a frontend person, I've only seen zero width spaces in three situations
- pasting from Word
- QA testers being through
- devs pranking each other
The third one is by far the most common. Word is much better these days and I've not seen that happen in a long time. I wish I saw QA test this stuff more often. The idea that it's common enough that you'd break your UX to handle it baffling to me.
I see weird spaces every time I copy-paste from some pdf pretty much, especially if it's a digitised or 10+ years one. Hardly an irrelevant use case
I'll be one of those guys. I see the invisible whitespace from pasting ALL the time. I've literally dealt with user complaints caused by it three times in the last two weeks! (Usually customer issues don't make it to me unless our support team can't figure it out or suspects a bug)
To be fair, it's not usually that frequent. Just a funny coincidence that I've JUST dealt with it more recently.
Add to that pasting from MS Teams.
"Break your UX" is a vast exaggeration. I'm not talking about phone number fields, to be clear. I'm talking about like numeric amounts, with maybe a negative or decimal point. It's literally just [0-9\.-] but that still requires JS to limit inputs to that.
What's wrong with
<input type="text" pattern="[0-9.-]*">
though?
It doesn't prevent the bad input, it only validates it on submission. Therefore it's on the user to fix it, and if it's from a zero-width space, it's literally invisible. Non-technical users will have no idea what to look for to fix it (i.e. use your arrow keys cursor to see at which character the arrow key doesn't shift visually, and there's the ZWSP). It happens way too often.
Try copying any string from any e-mail.
The problem here is that sometimes users and copy pasting from another document and that comes in arbitrary formatting, not the one enforced by the input element.
For example phone numbers can be a string of digits, or multiple strings separated by spaces or hyphens or with parts enclosed by () etc
It's a more pleasant UX to let them paste anything, then edit it inside the input, validate and submit.
> For example phone numbers can be a string of digits, or multiple strings separated by spaces or hyphens or with parts enclosed by () etc > > It's a more pleasant UX to let them paste anything, then edit it inside the input, validate and submit.
How is that more pleasant than a textbox which automatically removes the extra characters?
What if I copy something but accidentally get another couple words one of which is a number. For example copying from a chat app and get the date with the message. Then my "Sep 24th 416-555-1234" input which, would have been very easy to fix, becomes 244-165-5512 34. It will take me a few seconds to realize what has happened, identify where the intended phone number starts and remove the accidentally pasted digits.
The nice thing about the native input is that it is very simple, predictable and flexible. It may be easier to make a better UX on the happy cases but it is very difficult to not add some suboptimal and confusing UX on the less happy cases. Often times it is best just to keep it simple so that the user can easily complete their task rather than adding some "magic" which may backfire and confuse users.
It is surprisingly often that I need to open a text-editor or clipboard-editor to format values before pasting them into apps or websites because they have broken an input field by trying to be magic and failing to consider anything but the happy cases and maybe one or two bad paths.
I was talking about numerical amount fields, not phone numbers or dates or credit card numbers. Those are different things entirely.
FWIW if you're copying text on Android, you can tap the clipboard popup to edit the clipboard item before pasting it elsewhere.
The exact same problem applies. If I copy "Sep 24 $2412.45" out of a message and you quickly "clean" it to 242 412.45 I may not notice and even if I do it will take a second for me to realize what happened and clean up the value to be the intended amount. If I see the original text in the field it is much more obvious what happened and quicker for me to understand what I need to do to fix it.
> FWIW if you're copying text on Android, you can tap the clipboard popup to edit the clipboard item before pasting it elsewhere.
I never noticed that after 13 years of Android. I checked that now and I could not find a way to do it. Samsung's keyboard has a way to look at the clipboard but I could not edit them. Swiftkey does not. Maybe Google's keyboard? It's not on my phone. I looked at a couple of videos but they don't look anywhere like my phone. Not a feature to invest much time on it. If I have to edit the clipboard and I can't do it where I want to paste it, I open an editor and paste it there.
I'm using stock Android, Pixel 8 Pro. Highlight text then tap "Copy". See a toast in the bottom left. Tap on it (not the X) and a little text editor applet opens up. Here you can edit the text and save it, updating the value in the clipboard. Then using Gboard, it has clipboard history so you can see and paste the specific recent item from the past hour that you want. (Unfortunately it can't be edited after initially copying although you can long press them in the Gboard menu to pin for longer or delete them).
Because you don't know what your user wants to do and eventually you'll annoy someone
In most cases when you are accepting a numeric value it is best to just strip anything that isn't 0-9 then run validation on just the digits. There are some exceptions like phone numbers which may need + prefixes and similar but you can adjust these rules.
What I have found to work well is when the user unfocuses the input field or on submit strip everything but expected values then validate. If you want you can format the value at this time too (and the formatting won't interfere with text input).
If you want to get really fancy you can strip and format as they type and be careful to keep the formatting "virtual" such that the user is only editing the raw digits but this is very tricky to get right on all platforms and support all expected native editing UX. But even in the best cases this can have bad edge cases. For example the user pastes some text but it happens to have multiple numbers in it, if you eagerly strip and format what is left for the user will be these two numbers mushed together with misplaced separators or similar. If you let them paste, remove the unintended stuff, then format on blur this just works and is understandable.
Why blame it on the user, instead of fixing it?
You could remove the zero-width spaces in validation (for eg a phone number).
Or, you know, prevent invalid characters from the get-go. Same thing as validation, but done up-front. (But as I said elsewhere, I'm not talking about phone numbers, I'm talking about amounts)
I would like to allow people to copy-and-paste text in, and then edit it. That could be a longer text that has the amount in it (but also some unrelated numbers).
Because this often makes the input feel broken to the user.
Instead of asserting that "users are too stupid" as you have done earlier, perhaps programmers should be less stupid and write more permissive parsers.
Accessible design is actually pretty hard, and most designers and programmers get this wrong. If you want some good design advice, you can start here: https://adamsilver.io/blog/the-problem-with-live-validation-...
I'm not using "stupid" in the derogatory sense. I'm using it as a recognition of the skill/knowledge gap between technical and non-technical users.
To clarify, we get _asked_ by our users to implement fields that limit input to help them avoid mistakes. Our QA and UX teams agree. This isn't a unilateral engineering decision.
Yes, you want to provide guidance, but without getting in the way.
That's why I was suggesting letting the user paste in these 'wrong' characters, but offering help in removing them.
Of course, that's a trade-off. And it's more annoying to design and implement than just forbidding those characters from entering the input field in the first place.
I’ve read some very user hostile things in my career, but this one is particularly acerbic. It’s a bad look.
If I ever grew to hate users this much, I would find a new career. You should consider that.
I'm not being user hostile. I'm being cognizant that the skill levels of users is extremely wide, and to best serve everyone from a UX standpoint, it's best to limit the characters accepted in the input. It protects the user, helps them avoid mistakes.
From reading your comments, you're extremely user hostile and I hope to not come across anything you work on because they are the very definition of antipatterns
It's a decimal number field. There's no reason to have any other characters than [0-9\.-]* You're overreacting. You're attacking me for no reason.
Except if one copied it and it has a space in the beginning and your amazing script won't let one paste it.
[flagged]
Not everyone who disagrees with you is lying. Accusing people is a bad look here on HN. "Assume good faith" is the standard.
You can say "You're wrong". "You're lying", though, is almost never appropriate, and is, in itself, quite hostile.
Again “users are too stupid”. That’s remarkably hostile to users and doesn’t belong.
Please read my other comments. I'm not using "stupid" in the derogatory sense. I'm using it as a recognition of the skill/knowledge gap between technical and non-technical users.
Fine. But "you're lying" is also hostile, and also doesn't belong.
(I see that you edited that bit out of your post, so thanks for listening...)
> what's crazy is both of those still don't disallow non-numeric input
Which is really nice for copy pasting. For example, I have a number with spaces in it, and when I paste I get nothing or only until the first space because someone decided I'm not allowed to have non-numericals in the input field at anytime.
You shouldn't reject keystrokes as that can lead to silent errors when the user thinks they entered something that was not allowed.
And final validation needs to happen on the server side anyway - anything before that is just a usability helper.
exactly. Silently refusing input is an anti-pattern
> these arrow buttons
A spinner control, that is.
Spinners always puzzled me, to be honest. There is obviously a need for a compact numeric input control that both displays the exact value and allows rough changes using the mouse. Witness knobs in DAWs—which don’t actually work the way you’d expect from their appearance, you’re supposed to grab and then drag in a linear fashion, possibly ending outside the knob’s screen bounds. Or consider the weird input thing Darktable uses—which at least doesn’t mislead you with false skeuomorphism, but takes a bit to figure out. Then there are the inputs used for color grading in DaVinci Resolve. And so on. And all of them are nonobvious. Spinners are obvious, but they are also needlessly fiddly to use with the mouse, and neither do they provide the at-a-glance readability of knobs et al.
I feel like humanity just hasn’t solved compact numeric inputs yet.
> Spinners are obvious, but they are also needlessly fiddly to use with the mouse
I think that a quick improvement would be to let the mouse wheel "spin" the number up/down when the input element is focused.
An even better improvement would be having the `<input type='range'>` element actually display the value as it changed, and allow the user to set that value directly (say, by typing it in).
Right now, range is useless because the user cannot tell what is selected. The developer has to add in extra JS magic to let the user set range to an exact value, or to show the user the value they have chosen.
If `range` is improved in this way, then spinners are redundant and can be ignored.
> I think that a quick improvement would be to let the mouse wheel "spin" the number up/down when the input element is focused.
Firefox did that for number inputs for a long time, until very recently. They switched it off in Firefox 130 because people kept inadvertently changing values in forms while scrolling through them [0]. Personally, I've set the about:config option to reenable it since I've found it useful in certain interfaces, though I can't imagine it's much longer for this world.
[0] https://bugzilla.mozilla.org/show_bug.cgi?id=1741469
Isn't this same issue already solved for other scrollable elements? Scroll should only affect the individual element if the mouse was over that element when you started scrolling.
I guess the room for unwanted consequences is a bit bigger when the scrolling controlls the value instead of just the viewport.
That is how it worked, but people still found it problematic. E.g., from one of the comments on the issue:
> In step (3) here, if you do several mousewheel-spins while also subtly moving the mouse (just from placing your hand on it), it's quite easy/possible for the first spin to inadvertently change the value that you just entered (since step 1 had left the cursor hovering the input field, so that's where it starts), and then for the subsequent mousewheel-spins to successfully scroll the page. This can mean you change the number you just entered without noticing (and also without it being "in the middle of an existing scroll action", hence my note that this suggested mitigation wouldn't necessarily help).
The cause being that people don't look at where their cursor is before they start scrolling, and don't look at the value since they've finished entering it.
That's almost correct. I generally agree with hover == focus as a Window Manager level thing, but for document inputs within an application I still prefer required user interaction to set the focus location. E.G. a click, a tab, just move the line forward.
The correct context model is to not select an element for scrolling until it has been made the active element, and that UI element SHOULD have some sort of embellishment to make it obvious that's the focus.
Thanks for the tip wasn't aware of that.
I rarely want those arrow buttons for numbers
I think type=number is a mistake as it is too generic. It is difficult to get proper validation, UI and error messages.
It should be split into:
type=integer so the keyboard does not allow anything besides 0-9
type=decimal so the keyboard also allows decimal dot/comma and a fixed number of decimals!
type=float which allows for scientific notation, e.g. 1.2e42
And yet in both cases the browser insanely casts the data type to string when reading the value.
It’s amazing how many login forms are labeled “email” and then don’t have the correct type set.
From https://developer.mozilla.org/en-US/docs/Web/HTML/Element/in...
> Browsers automatically provide validation to ensure that only text that matches the standard format for Internet email addresses is entered into the input box. Browsers use an algorithm equivalent to the following regular expression:
> /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
Which doesn't even allow all valid email addresses :|
No support for quoted local parts. No support for punycode domains. Disappointing.
Use <input type="text" inputmode="email"> instead to just get the email-optimized keyboard on phones without the misguided validation.
It's not the fact that software engineering is broken saddens me as much as the extent.
Email is older than absolute majority of active developers and yet, it seems, simple knowledge like "what is email address" remains such an arcane knowledge that you are being looked at weird when present something a tiny little bit more correct than the status quo.
Where else can we assume that the common knowledge is flat out wrong?
>"what is email address"
Anything you can send an email to that is received, as far as I am concerned. I have my own domain, so why ahould I be forced to add an arbitrarily long string to it to be able to receive the mail? Or exclude <site>@myDomain.com from being input on <site>?
Or the worst of the worst: Disallow all but a few domains for emails.
At this point, not validating it cient side at all is IMO the correct approach, and instead send a verification email.
> Anything you can send an email to that is received, as far as I am concerned.
100% this.
The only acceptable hard validation is to check whether there is an @ between some characters. something like `.@.` in regex.
It makes sense to do sanity checking (soft validation) on client side. There is 99.9% chance that `muppet@gmial.com` is wrong, outright rejecting that is wrong, though.
> No support for punycode domains
Really? I tested with a punycode domain on regex101 and it worked fine, do you mean that it only works with ones already converted to punycode?
This is particularly annoying on mobile since on-screen keyboards won't adjust to an email input layout and autocorrect will screw up basically any email address as soon as a "." character triggers autocomplete to commit it's guess.
And password managers will not fill in the credentials correctly.
Get a better password manager? I use Bitwarden and it has never failed to fill out the login forms for me.
Bitwarden has failed me on some sites.
I think that in some cases this could be because the inputs accept usernames as well as emails. But not in all cases, which is annoying!
I found this very extended with "date" input. It seems that every single frontend library has its own date widgets, and lots of them look awful in small screens. You have to add a JS and CSS just for that widget, some depending on jQuery. True, some of them are very configurable, but with the tiny cost of "<input type='date'>" you have a widget that looks decent and native everywhere, probably cover your needs, and you can forget about it forever (e.g. no updates, no CDN).
A lot of those date and time pickers will fail WCAG testing as well.
In most cases, GDS now use just 3 text fields for day, month and year, but recommend pickers for dates close to today's date e.g. for booking an appointment, because a picker is easier if you don't know the exact date without reference to a calendar.
Sadly they don't currently have a recommended picker, but there's a useful discussion of what has been tried here:
https://github.com/alphagov/govuk-design-system/discussions/...
The native date input is terrible. Not the actual native control, which is usually okay, but the field itself. You can't even format the date! That's the number one reason I always use some datepicker library in combination with a regular text input.
IMO, you (the web developer) should not be formatting the date shown in the input widget. The input should be shown to the client following the system settings, so a US browser would show MMDDYYYY, while an European browser would show DDMMYYYY. And the field is correctly (IMO) normalizing all of them to ISO-8601 (YYYYMMDD) before sending it back.
And I have this opinion because I had to deal before with format configuration and normalization before saving to the database, when using a JS library. Now I just drop a "input type=date", and I know I'm going to get the ISO formatted date at the backend.
If my entire application used YYYY-MM-DD everywhere, it can be very confusing for users when the input suddenly uses something else. And often the locale or system settings are incorrect anyway. When I an working on a Dutch site with a Dutch locale and lang settings, then dates should be shown according to the Dutch locale, not according to whatever system of browser locale there is.
I always keep my OS and browser in English (makes searching for error messages sooo much easier) but I hate that I need to change my OS settings just to get Firefox to display the date in a proper way on some site.
If it works for you, I guess it's OK.
My apps usually deal with non-technical people (thus ISO in the browser input is out of the question), and sometimes spread at least between Europe and US (so people would enter MMDDYYYY and DDMMYYYY, and keep in mind that some dates work validate for both formats, namely every 12 first days for each month). Behind the scenes everything is ISO and UTC, but everyone gets their preferred format in the frontend.
I'm not getting your Dutch example. If I'm in the US and use MMDDYYYY almost always, and want to access some Dutch site, what date format would you show me in the input form? DDMMYYYY only because the backend is hosted in Europe? You will get wrong dates (e.g. 11/1/2024 for the first day of november, your system will store 11th of january) for at least half the US visitors.
Or maybe you are talking about "dates displayed" instead of "dates input", which is a different problem?
To be honest I would expect dates on a Dutch site to be shown in dutch format, just like I expect dates on American sites to be formatted in the US way.
Lets clarify a bit here. There are two different problems:
- Date display. I prefer to show it in the browser preferred format, but in the end what you say is also OK. It's a very minor issue.
- Date input. I would never force a format to the user, it there is any chance people from different locales can access the web. The correct way, IMO, is "input in the preferred browser format, send data as ISO". Any other combination would cause errors, e.g. "input in the preferred browser format, send data in that format" and you'll get wrong dates in the backend, or need to do a lot of gymnastics to avoid them. "input in server locale, send data in any format", and you'll get wrong dates from people used to any format that is not your server locale that happens to validate in multiple locales. "input in ISO, data send as ISO", you'll get users upset because "YYYY-MM-DD is stupid, use MY locale instead".
How do we know when a site is Dutch? Maybe check the URL to see if the TLD indicates?
I'm in agreement with showing/inputting dates in the users' regional setting.
<html lang="nl_NL"> of course
Unfortunately the number input is lacking and inconsistent. We’ve always fallen back to JavaScript validation.
https://jsfiddle.net/gaby_de_wilde/1qh4cax7/
I'm trying to picture a room full of <s>people</s> developers agreeing letters are numbers too!
Lets give the little people a slider but lets call it a range!
I really feel like they are trolling.
You start with a neat database table then you engage in an endless struggle trying to allow the user to edit a single row of it. It really feels like you are not suppose to do it. As if it was intended to be as annoying as possible.
They’d want 7 parallel lines, 1 red, 2 green, 2 transparent, 2 blue. Oh, and 1 of those lines should be perpendicular.
For the confused: This is a reference to "The Expert" sketch: https://www.youtube.com/watch?v=BKorP55Aqvg
`type=text inputmode=numeric` (from other comment)
Also, many things that look like numbers shouldn't be encoded as such, e.g. credit cards or phone numbers, are not.
E.g. any leading zeros get dropped out of phone number starting with a 0, very common.
I had to recently make sure that we do not use any of the more complex input elements, because we need to drive them from on-screen keyboard that for various reasons is also implemented in-page.
And that means it's barely doable with normal inputs, the special ones support even less events.
> because we need to drive them from on-screen keyboard that for various reasons is also implemented in-page
There's your problem right there. Can you expand on the reasons? It seems like very bad practice for a website to provide it's own "keyboard" instead of using the system keyboard.
This is for a closed system that unfortunately sometimes is supposed to be available outside[1] - a touch screen panel UI for (big[2]) embedded system.
It's hard to impossible to properly guide OS outside the browser regarding what keyboard we want at different points in time unless we end up also implementing custom keyboard plus some way to talk with it from JS. Previously we used a Chromium extension that could bypass some of the issues because it had privileged access and thus could send "secure" events.
EDIT: For some extra context - for reasons of ease of use, we want the keyboard of appropriate type (numeric, qwerty, other specialized layouts) to show in position related to actual input field, not take entire lower part of the screen like typical on-screen keyboards. For dealing with possible edge cases or otherwise making it more accessible, we also provide for the keyboard to be draggable by user.
[1] Sometimes it's accessed externally instead of in-person, for various reasons this means we have both the ability to open the web interface and use VNC.
[2] By big I mean we have a complete PC running Linux there, with intel CPU/GPU and an SSD
That use case makes sense, especially if this is an internal tool.
Isn't this use case already solved by phone browsers? Layouts are controlled via the inputmode attribute. Positioning the keyboard should be something solved by the host environment.
1. inputmode is very, very limited
2. "Solved by host environment" in practice means "worse user experience" as pretty much all of them simply use lower portion of the screen.
In comparison, the current draggable on screen keyboard I spent significant amount of time getting working allows the worker to drag the keyboard around if it overlaps a piece of information they need, as well as takes comparatively little space on screen enabling workers to better see what they are manipulating.
They could improve user experience everywhere if browser vendors wanted. E.g. why doesn't my (desktop) browser auto-complete recently-visited / bookmarked URLs when it sees type=url?
Privacy?
It's possible to display something in a browser without leaking the data.
My product just failed an accessibility audit because we are using native HTML form validation and the official recommendation was to implement our own validation layer.
EDIT: which I agree with.
Native HTML validation has many flaws and visual customization is not my biggest concern to be honest (but it's the nail in the coffin).
E.g.:
- It's impossible to show multiple errors at once per field unless you concat strings ("You need a number. You need a symbol. Must be >10 chars.")
This is both bad UX and bad for accessibility (you cannot navigate concatenated strings on the accessibility tree). And this isn't even implementation dependent, it's the spec! You need multiple errors at once because playing whack-a-validation-error is not fun for users.
- It's browser-dependent which is bad because you can't control it and because the implementation is generally terrible (e.g. in Chrome it shows a popup on focus, which is not very accessible by itself because (1) it's a popup (2) that shows modally (3) and can't show all form errors at once).
Not using popups for important information is accessibility 101, but browsers cannot afford to do anything else without interfering with the actual document.
- You still need custom validation for form-wide errors (like errors that don't belong to a particular field, "Fields A and B are incompatible") so you might as well have a consistent validation story.
- It requires you to have hidden inputs to be consistent (-ish) if you have some custom input that doesn't fit any of the native input types -- this breaks accessibility too and fixing it is as hard as having your own accessibility-friendly validation story.
- The custom validity API is imperative and cumbersome to use. Not using custom validity is almost never an option unless you want terrible messages ("This field is invalid")
And many more.
HTML form validation is terrible.
Thanks, that's quite interesting and insightful! Thank you for sharing
The fact that something provided by the browser can fail accessibility requirements is definitely ironic. We're always taught that the motivation to "use the platform" and "follow semantics and semantic elements" is partly to satisfy the accessibility concerns.
I still think it's worth to leverage the native validation mechanisms.
* You don't have to use the native validity tooltips for the error messages. You can read directly from the input's ValidityState (input.validity) and render the message however you like and show multiple errors if you need to
* The browser can improve and you will benefit from using a standardized approach
The fact that "not using popups" supposedly breaks a11y sounds weird, though. But if you need to respond to an audit then this is the way you can go.
> Errors that do not belong to a particular field
These are indeed interesting! There are techniques to handle those, too. In my project I have a "HiddenValidationInput" component that renders an invisible readonly input that serves the purpose of rendering a custom error that doesn't belong to any other field. It's in fact quite a pleasure to use because you can just conditionally render it.
> The custom validity API is imperative and cumbersome to use
Absolutely agree on this one, and handling this is exactly what my article is about. And I really hope that this part will improve in time, too
> You can read directly from the input's ValidityState (input.validity)
Feels like I don't gain much from that. Native validation is very limited and the few cases that it covers are super simple to implement already. Am I missing something?
I'd rather have a `validateSomething` which returns a discriminated union of error causes than using `pattern` and just getting a boolean.
> In my project I have a "HiddenValidationInput" component
Yeah, that's an accessibility issue (and the UX for the common user is terrible too for multiple reasons).
Interesting, because for my apps, I implement all those validations. The form wide validation are done on server. Basically I have a bunch of layers of validation that leverages everything. Chrome having a shoddy unaccessible design is Chrome problem, I would file a bug report.
> it's the spec
This one? https://html.spec.whatwg.org/multipage/dom.html#concept-elem...
I don't see anything that defines how validation messages should be presented (not even that they should be present)
What was the auditors' reasoning for that?
That the browser implementations are generally terrible and wouldn't pass accessibility audits, so all browsers would have to change and then some time to pass for the fixed versions to be widespread.
We didn't discuss browser-specific issues in detail, but I edited some points in my original message that highlight some of the issues that I suspect make it a no-go for accessibility.
Seems to me that this says that the browsers have the accessibility problems and that's what should be fixed. Why does every website developer have to work around this while the browsers get a free pass?
If field validation is "standard HTML" and browsers can't do it in an accessible way, that's squarely a browser problem.
Because in reality browsers can't do much. The API and spec are broken as-is.
I'll quote my top-level comment:
> This is both bad UX and bad for accessibility (you cannot navigate concatenated strings on the accessibility tree). And this isn't even implementation dependent, it's the spec!
> Not using popups for important information is accessibility 101, but browsers cannot afford to do anything else without interfering with the actual document.
Plus it doesn't matter who's to blame: people with accessibility issues need access now.
> Why does every website developer have to work around this while the browsers get a free pass?
Because browser makers are merrily taking that free pass, whether we like it or not, and people who need accessibility allowances need them now, or better still quite some years ago, rather than at some future time after we've nagged the browsers into taking useful action.
It isn't entirely the browser people's fault, there are significant issues in the spec, as already discussed in these comments by people who know more about it than I, and that is part of why they feel justified in taking the free ride, but as some of them were involved in the original specs and they are in a position to propose alternatives & deliver PoC implementations, it is more their responsibility than they think. After all, Google in particular are more than willing & able to invent new specs¹ and throw implementations into production, when there might be marketshare, stalk^H^H^H^H^Hadvertising income, or protection money² on the line.
----
[1] and Apple deliberately break them, old or new, in a fit of pique!
[2] Nice app/extension you have there, it would be a shame if it started failing store inclusion reviews, or if APIs had breaking changes for our benefit underneath you.
totally And if they fix it, it'll be fixed for everyone
In an all honest reply, is that the people that writes these specifications, live disconnected from the reality, they don't use the stuff they specify. That stuff works for very simple things, but then when your forms evolve you realise you will be better off just writing the whole thing yourself.
This. Doing relatively common things like cross-referencing from other fields ("did the user specify a country? If so, we can validate the postcode/zip code they just entered, but if not we'll have to wait until they pick a country") almost immediately require JS to handle, and as soon as you're using JS then it's all just easier to do in code than trying to mess around with validation properties.
Yep. This is great until you need a cross-browser date picker, at which point you need to implement a bunch of stuff yourself. It’s frustrating how primitive HTML forms are, after so many years.
What do you mean? Most browsers support <input type="date"> natively just fine.
> What do you mean? Most browsers support <input type="date"> natively just fine.
The `<input type=datetime-local>` on FF has a broken time-picker[1], has always been broken, and there are no plans to ever fix it, ever.
[1] In that it will let you pick a date, but not a time - the time must be manually typed into the input!
What's hilarious is they do have UI for it in about:config "dom.forms.datetime.timepicker". It makes me so angry that it's not on by default. It works fine!
On Android, the date picker widget is fiddly to use for selecting distant dates, like date of birth. Not impossible but requires many many taps.
That's an implementation issue, not a specification issue. The specification just suggests the user is shown a date picker.
You’re technically right but that doesn’t matter.
That you’re correctly using html forms won’t quickly lead to browser improvements.. so the result is that users will hate your forms. Users/your customer might possibly even think that you’re to blame, and not $browserVendor.
I’ll go one further and say that the customers are absolutely justified to blame the developer instead of the browser. If a developer knowingly chooses a built-in form control whose common implementations are bad for their users, how are they not at fault for the resulting experience?
“This site only uses functionality provided by the HTML spec” is not a useful goal in and of itself. Using the right tool for the job, which might be JavaScript, is always more important.
It doesn't really matter whose fault it is, the end result is that your users have bad experience on your website.
I've never had a problem with that myself. I guess people don't know you cab tap the year in the date picker to quickly go back a bunch of years?
Most of the forms features are from the early 90s. You're not working in the same millennium as some of the specification writers.
The `required` attribute, which this article is about, is an HTML5 thing and first appeared in browsers in 2010-2011. So sure, not brand spanking new, but the web was already used to write modern apps. There's no good reason for the validation features to be so shabby.
Even 'required' doesn't work properly. Browsers do very odd and inconsistent things when your required field is hidden when submitting. Like in a basic tabbed or multi-step form.
If you have a checkbox with a label, please a "for" attribute to the label so I can disable/enable the checkbox by clicking the label. This is one of my biggest pet peeves, maybe its just me.
Wrapping input into a label also works. Not sure why people tend to separate the two.
And also why browsers started separting these. It’s a checkbox and radio that should contain a text, not vice versa.
One reason I have heard about is implicit labelling doesn't work with all voice control tech, including macOS voice control[1]
[1] https://a11ysupport.io/tests/html_label_element_implicit
Not just you it's a required feature of accessible sites following ADA/WCAG.
Here's a simple example that doesn't use React:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectE...
I was thinking that it's so weird to talk about using standard HTML validation and then everything is shown with React? If we want to teach people how standard works, we can't assume React as the default.
I addressed this elsewhere in the comment section, but there's not much "react" going on in the article. I do think that JSX is very expressive and the concern I cover mostly involves the declarative "component" model for writing UIs. It's not react-specific.
I believe you could probably do most of that with just css now too. Disabling the default pop up from showing up may be the only thing you need javascript to do.
Html form validation is great. There's just one gigantic catch:
It doesn't work in Firefox for Android.
https://bugzilla.mozilla.org/show_bug.cgi?id=1510450
I'm using Firefox on all of my mobile devices but I can't blame devs for ignoring FF for Android on this one. This is an API every other browser had working 10 years ago, it's on the Firefox team to sort out this mess. The less than a percent of users who don't see the error messages for controls marked in red isn't worth ignoring the standard for.
The more websites use this, the more pressure Mozilla will feel to fix their browser. This isn't something like WebMIDI or whatever API Chrome or Safari implemented before standardising, it's part of the original HTML5 spec.
Firefox for Android has a smaller user base than Samsung Internet and Opera. It's 0.5%. It's a waste of time working on supporting it. Especially considering how little time people put into making sure their sites work for people using accessibility software. I don't think it's worth mentioning in these issues unless you're also ready to talk about UC Browser.
Is that somewhat biased? - I assume the number of people using Firefox has a quite big overlap with people using ad&tracking blockers, which block many statistic sites. (Website operators may log user agent which will be somewhat accurate still)
This is always something I question whenever the analytics numbers come out. I know my adblocker blocks GA, so I'm not going to be included in any GA statistics.
Every time I've asked a marketing person about this they get hand-wavy about "it all comes out in the wash". But meanwhile they say things like "our analytics show that our market is mostly older and non-tech-savvy people". I'm not sure that the analytics numbers do actually show that. I think that's just the demographic that you can see.
I wanted to quickly check the 0.5%, and see 1.2% in Japan for instance, where iPhone have near 80% share.
https://gs.statcounter.com/browser-market-share/mobile/japan
That's still not a lot, but above 1% is a decent threshold to decide to support a browser.
Yay, I'm in the point five percent!
As a daily Firefox on Android user, not catching up on standards is what hurts the most. Most painfully to me, all the WebGL stuff like [1] and some minor annoyances like [2]. Still, having uBlock origin among other extensions is a killer feature.
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1884282
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1897707
It's much worse than "doesn't work": the validations work, they just don't show any error. It would be okay if validations just weren't implemented, but this is just absolutely fucked. I discovered this years ago after a long and painful debug session, and I'm quite sure I wasn't the first or last to go through that.
I just realized this having switched to FF on Android fairly recently. Working on an app and saw literally nothing when trying to submit an empty required field. Couldn't imagine what I was missing until I searched. I was stunned. No issue with rolling your own validation but this should work!
That's weird, caniuse says it works: https://caniuse.com/?search=constraint%20validation%20api
You gotta be careful about going overboard with it.
Recently I was trying to get a refund on Groupon because the company I'd bought a Groupon for was under new management that refused to honor my groupon.
The form had a stipulation "minimum of 15 words". Try as I might, I could not get the form to pass validate until I inspected the HTML.
Literally zero allowance for any sort of punctuation.I don't think this is particularly pertinent to HTML validation. This is true of any type of validation. The same rule could have been applied on the server, and then you would have had no hope.
Exactly. My rule of thumb is "don't add validation until there is absolutely no better way and you absolutely must restrict this input."
That's actually a good argument for the point I was trying to make. Existing validity attributes such as "pattern" are cool, but not enough.
E.g. the "repeat password" example is actually achievable without "setCustomValidity" by using the "pattern" attribute. For that, you would have to dynamically construct a RegEx out of the value from the first input. I didn't want to make the article too long by comparing the solutions, but the point is, with the "customValidity" you see how much more eloquent and easier to read the validation is. So a nicer API here makes all the difference
The "15 word minimum" constraint would look so much nicer as "value.split(/\s+/).length >= 15".
There’s a reason it’s heavily underused. So many frameworks and libraries provide robust, style-able validation capabilities, some with very sophisticated and extendable functionality. Don’t torture yourself if you don’t have to.
You also have to implement your own validation on the backend anyway. There's always going to be someone trying to fiddle around with your form, either using some weird browser, curl, or some other tool that doesn't have the same form validation built in. You're not going to trust that the client actually did the validation, or did it correctly, so the backend still needs to be able to validate input and show the form, with validation errors, on all fields.
Frontend validation is only there to be helpful for the user, but if you can style it, or trigger it from the backend on submit, you have to implement your own styling anyway.
Agreed.
We try to use browsers standard features whenever possible. Despite looking into using the built-in validation, it's never been worthwhile. Too many gotchas, and we end up using a library to be able to easily support more complex checks anyway.
Furthermore, using a library opens up, in some cases, the possibility of sharing some of the validation code between front and backend.
In particular this article seems to work around one of the issues with `useLayoutEffect`. Not something that should be done lightly.
One of the things I dislike about HTML form validation is it starts running from page load. So if e.g. you tie error state formatting to it, the form loads up with a bunch of errors which may be intimidating to the user.
There is the :user-invalid pseudo-class that lets you avoid this to some extent, but it has some inflexibility that may mean it isn't enough, depending on your use case.
https://developer.mozilla.org/en-US/docs/Web/CSS/:user-inval...
There ought to just be a property named something like `defer-validation` that does the right thing. But I'm sure I'm not the first person to suggest it, there's presumably some logistical or technical difficulty.
If I'm making a wish list I'd also like to point a property at a handler function that accepted a `string` and returned a `string | null` (or at least a `nonempty string | empty string`) rather than using an onchange handler, but it is what it is.
This is one of the main reasons people started using JavaScript, to show errors only after a form has been “touched” or right before it is submitted.
A bit perplexed by your comment. That wasn't a main reason people started using javascript.
I even remember when people started evangelizing client-side validation in the mid-2000s. Javascript was already a normal tool used in web apps by then, and most web developers would regularly be adding javascript to their apps.
Back then it was a bit of a pita as you had all sorts of gotchas with javascript memory leaks by registering change events on controls. I can't even remember the term now, but you could basically have a circular reference between a closure and a control and so it wouldn't cleanup properly.
Also, modern developers probably can't even begin to imagine how slow javascript was on IE6. A loop of a few 100 iterations could bring it to an unresponsive halt.
probably they mean why people started using JS in form validation, and not JS altogether, although agree that isn't the reason either.
Correct, I meant that client-side validation driven by JS became popular because of UX issues when using pure HTML. There have always been plenty of other reasons to use JS with forms besides validation. But it’s notable because forms and form validation are such common building blocks that if people feel the need to use JS there, it kind of infects everything else around it. IMO, being able to build high quality form experiences without JS is critical to reducing bloat on the web.
JS form validation quite significantly predates HTML form validation. The alternative was server side form validation, for the longest time. HTML form validation was meant to standardise and reduce the need for JS validation, but for UX reasons it hasn't really managed that. And that you'll need JS anyway if you're doing validation specific to your business logic that doesn't fit into the set of rules HTML validation has.
I've never understood why this was chosen as the default experience. Most users don't enjoy having every form element yelling at them for actions they haven't even had a chance to take! You can script around this, but at that point the feature isn't doing much. I'd argue this is the biggest reason you don't see more widespread adoption.
Perhaps the same reasoning that IDEs show syntax errors before you save the file? (No, I don't like that feature either.)
My personal bête noire is sites that misuse type=password for 2FA inputs, since that confuses password managers and browsers both.
There is a way to annotate it. autocomplete=one-time-code
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes...
True, but vast majority of websites don't do the right thing. So password managers need to manage a database of form input overrides. I worked at a small company building a password manager and it was a bit of a nightmare, we had to allocate support staff resources to handling reports of website incompatibilities.
I'm curious, why did you implement your own password manager?
I worked for a small company that did. The idea was the password manager lived only on your phone, and you'd connect it to your computer in various ways. Notably including our own hardware, USB nub that connected to the phone app via Bluetooth and acted as a keyboard for the device and the app would instruct it to do the keystrokes to enter your saved credentials. Also a browser extension that the app would connect to over websockets (through our relay servers, DH key exchange to encrypt the connection end to end) and the extension would request the app to send down the credentials on demand. Also we were a very early adopter/implementor of FIDO U2F (security keys). The product kinda hinged on the paranoia of the userbase (which I never aligned with, I trust 1Password and cloud sync'd encrypted vaults for example) so it never really took off. It wasn't "my" product, but I worked on it for a few years, right out of school.
Also completely unnecessary for passwords that expire in 30 seconds.
Because it sucks.
It does not translate with the application but with browsers settings, it doesn’t style or fit any design. It looks differently on different browsers and it is really hard to explain to stakeholders “this is from browser I don’t have control over it”.
> It does not translate with the application but with browsers settings, it doesn’t style or fit any design
Wait, which is it? Does not match any style or design, or is it matching the browser's?
And if your application isn't consistent with the browser and OS settings, shouldn't you fix your application?
It does suck, but I think not for the reasons you mention.
I truly believe a nicer API would motivate developers to use it, and if native validations satisfy the product requirement, their styling does become a lesser concern.
But surely styling is still important, but another great topic to write about is the fact that you actually can opt-in to showing native validity errors in a custom way!
And your application should be looking at ... the browser settings.
I could see a case, if a user decides to somehow make a single website use a different language than the others. I guess it would be a browser's job to have specific languages for specific websites.
It works for presenting or selecting initial language. Even that is debatable because some big players don't even care about that and present language based on location.
Explaining to people they should go and change their browser settings is major hassle.
Automatic language selection based on location is an anti-pattern. If I am traveling, I don't suddenly switch my brain to another language. Whoever writes websites like that doesn't properly think about it.
The real problem with client-side validation is you can't trust it.
You need to revalidate on the server, no matter what.
It's not a security feature, it's a UX feature.
I'd argue it's often an anti-feature.
These validation at input can be super annoying when you're copy-pasting your strings from other sources, and want to edit them in textbox in-place. Especially if you're on your phone.
I've be frustrated by this on numerous websites, a lot.
Another common failure case is only updating the validation state on key presses but not other content changes like auto fill.
True, but if there's a communication bug between UX and back-end teams, that can escalate into a false sense of security and then an exploit.
What the hell back-end team relies on their front-end teams to tell them to do input checking?
Nothing my front-end people could possibly do would trick me into trusting user input.
in 2025? you'd hope not
but also cross-system context switches, amateur RegExp, escape character (ab|mis)use, etc. can make "user-input" propagate farther than any one team's boundaries.
assertions/test coverage/fuzzing at every boundary so user-input taint analysis can't fail is a requirement for a system that passes user data around more than one time or tech stack.
> True, but if there's a communication bug between UX and back-end teams, that can escalate into a false sense of security and then an exploit.
How so? The backend ALWAYS validates. No communication necessary, whether or not the frontend also validates doesn't matter to the backend. Frontend validation is to improve user experience, nothing more.
>Frontend validation is to improve user experience, nothing more.
and to reduce server load.
"We always validate - no need for _me_ to do it" type bystander effect / diffusion of responsibility.
That's one benefit of using ts on server. We share same zod validation on both end.
You were being downvoted here, but I think you make a great point.
The problem with having separate client-side and server-side validation logic is that you (generally) want the rules to be the same, but you end up needing to write them twice, usually in completely different technologies. I have seen many, many cases where the client-side validation and server-side validation got out of sync, and then just like you put it, obscure bugs or security exploits can arise from this.
In general, I think client-side validation should really only be used for the basics, often with respect to type (e.g. the email/URL examples given) and just basic "required" (non-empty) fields. Anything more complicated than that should be done solely server-side in my opinion - e.g. I wouldn't use setCustomValidity with a complex set of client-side rules. What I think is important, though, is to ensure that if the server validation fails that the error message that comes back is not just a single "Bad input!" message, but errors can be keyed by field to ensure you can display field-specific error messages and error highlighting.
Another option I considered back in the day when my backend was on NodeJS is to have the server return the text for a JavaScript validation function before the form itself is actually rendered. This, this function can be run client-side for immediate feedback when the user submits the form, but it's also the exact same logic that is run on the server when the form values are received.
This was one of the biggest "oh shit" moments I had when learning Remix: I could reuse the same validators across front and backend and they could even be right there in the same file.
It's a UX feature, absolutely, but you can't trigger the browsers validators from the backend, so you'd need to implement your own styling anyway, probably even add a bit more information than the browser can natively handle.
Couldn't have said it better!
simply adding required is all you need.Not required=true The omission is equal to required=false. No one really write required=true, they just add the attribute `required` only by its self. This is one of the odd quarks about html attrs
Same is true for things like disabled ect https://developer.mozilla.org/en-US/docs/Glossary/Boolean/HT...
> The strings "true" and "false" are invalid values. To set the attribute to false, the attribute should be omitted altogether. Though modern browsers treat any string value as true, you should not rely on that behavior.
in other words required=false may still end up making the field required. FYI.
They've used `required={true}`, not `required="true"`, which is JSX, not HTML. The one with curlies isn't even valid HTML. In the old HTML spec, the correct value, if you wanted to set a value, was to set `required="required"`, but these days the spec is looser since it tries to conform to the web, not the other way around.
Even in jsx its not required to add a boolean value. Unless you are passing in a var as a prop in which case sure. But that didn't look like it was the case in these examples.
One of my favorite eslint rules to enable: https://github.com/jsx-eslint/eslint-plugin-react/blob/maste...
> Even in jsx its not required to add a boolean value
Absolutely true! But I like to do it because I personally think it reads more nicely and is more explicit and that's what I do in all my projects. But it is indeed a matter of taste and I have nothing against code that follows the convention to omit the "true" value.
They've written it in JSX, I think, not in HTML.
>Imagine a username input that should be valid only if the username is not taken
Maybe that is user friendly but for sure I don't like to see the backend bombarded with API calls each time an user types a letter.
You usually create debounced inputs for that. This is similar to the autosuggest and typeahead inputs and comboboxes: sending requests to the server in response to an input change isn't something unusual
It’s a major security/privacy issue, you don’t want to tell world+dog all registered users, especially since that’s typically an email address.
Huge, huge, massive “no no”.
Likewise you still have to do sever side validation as any client side code can be modified, or you can just send payloads directly to the server. IMHO client side form validation is dangerous as it gives a false sense of security.
It's not actually all that bad, if you do it asynchronously and in batches (as much as possible).
The total amount of traffic in both direction is pretty small, and the logic is simple, especially compared to lots of other things your server is typically doing.
WebSockets, then it's a couple bytes a click
I don't think the amount of traffic is necessarily the issue. You're validation could be fairly "expensive". Maybe you need to do a lookup in a legacy system, maybe you need to check multiple systems?
You'd probably have to wait until the user moves on to the next field, if there's more, but that's also a little silly, as you'd force the user to go back to a previous field.
Ya'll may want to checkout Valibot¹ or Zod² in conjunction with something like React Hook Forms³ or the more agnostic Tanstack Forms⁴. Really sweet form validation that's concise but as precise as you want it to be.
The problem with vanilla form validations are (1) they're so basic that it's table stakes for any library or framework in this space, even ChatGPT can do it well, (2) there's an enormous amount of other validation scenarios they don't cover, and (3) unless your validation is simple and doesn't require a validation library, now your logic is split between two places.
[1]: https://valibot.dev/guides/comparison/
[2]: https://zod.dev/?id=basic-usage
[3]: https://www.react-hook-form.com/get-started/#SchemaValidatio...
[4]: https://tanstack.com/form/latest/docs/framework/react/quick-...
> there's an enormous amount of other validation scenarios they don't cover
Can you provide examples of those? Genuinely interested as I'm on a quest of creating a list of recipes that show that native form validation can be just as capable as custom validation libraries
The best native HTML validation is server-side validation.
The only downside: the user has to wait 300ms.
And he loses his page state if there is an error. You have to do server-side validation regardless, but client-side validation can be a lot more pleasant for the user.
I used to think it doubled your workload to do both, but if you are using JS-free client-side validation, I think that the server can just return an HTTP error guilt-free for any invalid input that the browser will catch. It’s a pretty good compromise for format validation.
When returning an error, you can fill the input values in your HTML response.
Indeed the most pleasant UX is to set an additional validation logic on the client side and I don’t think this should the go-to solution.
Using your browser's back navigation from the error page to the form should result in the values still being there unless you are doing something stupid with client-side rendering.
> And he loses his page state if there is an error.
No, you can handle that on the server too, easily, since you can fill the form with the last known state upon page loading.
Great answer, exactly! Client-side validation isn't meant to remove the need for the server-side checks
Assuming the actual validation of form input takes ~1ms, this is a fairly unusual amount of latency to experience in 2024.
You've got tech stacks and cloud services that will put you within 20ms of 99% of your users.
Server side everything is still the safest possible bet you can make.
The best solution is to use HTMX (or similar) to hook into your server-side validation so that you only have validation code one place (on the server), but you don't have to wait for complete form submission before finding an error in a field.
Example: https://htmx.org/examples/inline-validation/
I share the wish that there was more effort in the browser space to improve the built-in controls but I would also recommend that people thinking they can easily do better try some real usability and especially accessibility testing. One very nice trait of the standard APIs are that they’re very lightweight and people who build assistive tools like screen readers and Braille displays know about and support them.
It is so easy for developers to think they have something better after a simple NPM install, until they test it on a slow (i.e. median) phone or watch a blind person try to use their application and then spend weeks trying to improve things. Given how common web forms are it’d be really nice if we had an Interop-style competition focused on making the out of the box experience better for normal people both for the controls integrated in browsers and the myriad of JavaScript widgets.
It's also easily misused. Take the regular expression validator for passwords on the California DMV website, for example. The website states "Must include at least 4 alpha characters". But the validation pattern
requires that these characters appear consecutively.The {4} is being applied to the whole group which includes a .*
Isn't that correct?
Yep, and the .* means "0 or more of anything", so it's 4 or more groups that each end with a letter. They can be consecutive or not and a group can be a single letter but doesn't need to be - so whatever the failure was, it wasn't that (or the regex was typo'd here to be correct instead of what was actually on the site).
The regexp still requires four letters before the last digit or special character which is a weird requirement.
The (?=…) are "lookaheads". They match the enclosed pattern without advancing the cursor.
That's exactly the case where the "customValidity" attribute shines!
I have nothing against regex and the "pattern" attribute is the way to go for many cases, but having this is an alternative is also very nice:
const valid = value.length => 4 && isAlphanumeric(value); return ( <Input value={value} customValidity={valid ? 'at least 4 alpha characters' : ''} /> )
AFAIK customValidity is not an attribute and you can only use an imperative setCustomValidity API which is terrible cumbersome to use in a declarative framework like React.
Yeah this is exactly what I'm writing about in the article :)
Yeah well I promise it does read nicely when there's formatting which HN comments do not allow :)
Bizarrely, url validation requires the https:// prefix
I do get the point of using form validation clientside to ensure a better ui.
But dont remenber to also verify serverside. Anything clientside can have been fumbeled with. (Also kinda anoying to have to duplicate this tho)
> Also kinda anoying to have to duplicate this tho
Oh yes it is...
I once worked on a project where we had a tool that dynamically built client-side forms based on each customer's needs. After rolling it out for a big customer I discovered (after the original engineer responsible had already been fired for other reasons) that all of our dynamic forms had NO server side validation. none, zilch, nada.
We did have client side validation though, a good amount of it and nearly all of it was using native HTML features, and we had the whole form available server-side as well. So given that I was under a crunch, on form submission I loaded the HTML form server-side, manually iterated over all the elements and re-implemented the validation checks that were embedded in the HTML. Crazy times, but heck it was flexible!
You could fill those setCustomValidity() calls in the client with rule-sets generated on the server.
even re-fetch them from the server on each input change in the client
or just ditch the whole thing and do it in htmx :->
Or do all of the above https://dev.to/yawaramin/handling-form-errors-in-htmx-3ncg
Could you not remove the event from the input change, replacing it with NOP?
htmx looks dope af thanks
I think it's a trilemma between security, convenience, and architectural sophistication (NB: I'm deliberately not saying complexity, because the code doesn't necessarily get more complex). It is usually physically possible to find a solution with equal security for a given level of convenience, but it will require an investment of creativity and possibly refactoring to realize. Both of those things are very expensive.
To take an extreme example, you could ensure that validation happens identically on both the back and front end by writing your own framework with that property. You could create a framework with no more security bugs than the next best alternative and while providing great UX. But writing a framework and shaking out the bugs is a huge lift.
So in practice you can't go all the way out on the third axis and it is approximately a dilemma. But if you're on the lookout for exceptions you may find an opportunity to cheat/curve bend (eg as suggested by other commenters, when using JS for the front and backend, you can use data modeling libraries like Zod to get most of the benefit for a fraction of the price of writing a framework).
Ultimately the risk transformation is exponential; don't roll your own crypto, don't DIY authentication/authorization, don't risk your own inconvenience and assume security.
However the opposite, to use all the "agreed"-upon code, introduces a near similar surface area of risk, simply spread across more vectors. And because the vectors are spread, and the system is more complex, the dissolution of responsibility leads to the opportune laziest option - patching code together, trusting it works.
it would be wise to question why this convention is so normalized.
Just to put it on the record I am happy to acknowledge that duplication is an inconvenience as well as a security issue.
Your point about trusting conventional code is well made and important. Once I repeated that I shouldn't roll my own crypto. A cryptographer shrugged and told me, I mean, somebody has to write it, and that person might be you. (That person isn't me. I don't roll my own crypto. I do roll my own auth, because I'm comfortable with my understanding of authn/authz attacks. Use my software at your peril.)
Regarding complexity what I was thinking is that, after a lot of clever reflection, you might realize the proper solution is actually to take something away. To give an illustrative though not very realistic example, you might realize you didn't actually need a web backend at all and that the app can function local-only. Thereby solving your UX and security issues - client side validation is now completely acceptable. This architecture is simpler (less complex) in that the diagram contains fewer elements, but more sophisticated in that it contains more baked-in wisdom about how your normally web-based application can fulfill all it's requirements locally.
Flask-WTForms will generate the same validation both client and server-side. Is that not usual?
It's a bit disappointing that articles talking about HTML use JSX/React syntax instead of actual HTML (even more so not actually saying it). Example from the article:
I thought the same thing.
I was once discussing a third-party integration with a React developer. The integration required that our app POST a couple of fields to the third-party's site. I found that the developer was struggling with the integration and they were asking me questions about it when I said something to them along the lines of "It's just an HTML form, with a couple of hidden inputs that when submitted make a POST request to this URL" they said to me "Yeah, well HTML is kinda old, it's not really used anymore"...
I'm sure I've said plenty of stupid things when I was green but I hope no one remembers them like I remember this one. It lives rent free in my head.
It's definitely true that many developers would benefit a lot from learning more about the basic HTML and the web platform. But I refuse to support the notion that this is somehow React's fault.
In my personal experience, react allowed me to rely more on the native web platform APIs, not less, than other frameworks (at the time that I switched to react)
> they said to me "Yeah, well HTML is kinda old, it's not really used anymore"...
> I'm sure I've said plenty of stupid things when I was green but I hope no one remembers them like I remember this one. It lives rent free in my head.
I'm doing gigging while my product is gaining traction. Last week, I received this verbatim rejection for a PR review at a client, who's oldest developer is 27:
"No, we don't want all the logic in the same place. You must split the logic up"
This is also one that will take up valuable space in my head till the end of time :-(
(PS. Yes, I split the logic so that it was evenly balanced in 3 different programming languages, instead of having the entire logic in C# alone)
The confusion in the article is so complete that I'm left wondering whether or not the author is aware that what they are writing is not, in fact, HTML.
Yeah, I am aware! Thank you for the concern :) I did address this in an adjacent comment, but I'll say again that I did contemplate over using JSX or not. Also yes, it may have been a good idea to add a disclaimer for the fact that the code I'm showing is JSX, but honestly there are so many other disclaimers I had in mind, all of them together would make the article twice as long and much more boring
It's exacerbated by the fact that the API they propose to make custom validation more ergonomic works for React, but would be much worse for plain Javascript and HTML.
The API I'm proposing would indeed bring much more benefit when used in a declarative way. That's the point I'm specifically trying to convey in the article.
I don't think I understand how it would be "worse" for plain JS and HTML though. Would love to hear your thoughts.
Actually, there is one possible concern. When HTML is returned by the server includes inputs with set "custom-validity" attributes and this HTML gets open by a browser with no javascript enabled, this would make the input "stuck" in an invalid state. This is an important edge case to consider but I do believe there is a resolution that would satisfy everyone
In plain HTML, you can't do:
you can only use a static string for an attribute. So you'd need an event handler to set custom-validity from javascript when the input value changes, then a handler to setCustomValidity when custom-validity changes.In other words, it's the same exact imperitive interface as setCustomValidity, except with an extra layer and the extra event handling has to be implmented along with it.
If I had a say, I'd go for an interface where custom-validation would take a javascript function name, and that function would take the value as input and optionally return a string with a validity message. Or it takes a javascript snippet like onclick, except one which returns an optional string value. Then again, there wouldn't be much difference from onchange.
Edit: to counterbalance some of the criticism, I think the article is very nicely written and formatted, and the interactive components are a good touch.
Sorry to disappoint, I did hesitate over this. But JSX is honestly very nice to read and also I didn't want to leave the impression that opting in to native form validation somehow forces you to not use javascript. And combination of javascript + html is, again, very nicely expressed with JSX.
The concepts are obviously easily translated to other component frameworks, but they also do apply to pure HTML and vanilla javascript.
The problem I am highlighting in the article is the absence of a declarative nature to the Custom Validity API, so I think it makes sense to use a declarative component approach in code examples
once you grasp the ergonomics of setCustomValidity() you can go crazy e.g. pass it a multitude of validation rules per input field.
unfortunately you’re sort of back to square one if you want to implement warnings (ie suboptimal inputs but still workable).
Edit: While grasping the ergonomics produces euphoria like solving a complex puzzle it’s also a hint at the pain un-initiated colleagues will feel when tasked with maintaining the code.
After reading all this, I think I'd still choose to do it away from the browser built in capabilities. I'd rather have full control over the process and the design than rely on the limited capabilities of browsers.
The browser is programmable; at this point they should stop getting clever about adding built-in functionality and instead just expose better ways to use the browser as a dumb UI toolkit.
Couldn't disagree more. Browser features can be much better at handling edge cases: disability, localisation, unusual devices, different input methods, weird screen sizes, etc... rather than hoping every developer does it right, building that in is more efficient and consistent. The common cases should be handled really well by browsers.
I couldn't disagree more; it might be good for disability but for localization, unusual devices, different input methods, weird screen sizes I have never seen that well executed by browsers. I almost always prefer a more full-featured alternative from a standard framework than whatever is lowest-common-denominator feature in a browser -- which also, depending on the browser, may or may not work the same or may or may not even exist.
The browser should provide low-level capabilities and let developers build the high-level functionality from it.
This article ultimately supports this by showing us exactly how half-baked this particular browser feature happens to be.
Browser functionality is typically (handwaving on exact numbers here) better than the worst 80% of sites, on par with the next 10%, and not as good as the top 10%. If you're putting in the effort to build a site in the top 10%, sure, you might not want to be "held back" by the browser. But the vast majority of sites would do better by using what's built into the browser.
And I would argue that the value the user receives from that top 10% of sites is not commensurate with the pain the user receives from the sites that think they're in the top 10% but aren't.
I don't know, what browser functionality are we talking about? Even this form validation has to be implemented; I don't think I've ever even seen it in the wild.
What percentage of websites are rolling their own functionality instead of using any one of the various library and framework that do this better?
There is no way that every single browser is going to implement some high-level feature in a satisfactory and future-proof. It's the wrong place to do it. Almost every attempt has been at least a partial failure. We might get something maybe a decade after it's in common use and then only the most basic version of that. And we get browser bloat for our troubles too.
I don't use the standard <select> controls in apps anymore because the build-in version is too simplistic. Don't even get me started on file uploads. Is everyone just supposed to be held-back by the minimum a browser can do everywhere? Why waste browser developers time building things that no one really wants to use.
As a user, I want common UI controls to look and behave the same way across all web sites. Ideally, across all applications on my OS, but that's also a lost cause. POLA[1]. I can accept if the developer wants to somehow extend an existing control to support something new, but it's so irritating when they just re-implement their own thing entirely because they think their ideas are better than the browser's. Multiply that mentality by every site out there, and you have the web as it is today: Everyone's site looks and feels inconsistent with every other site. And everyone ships a different 500 lines of code, each with different bugs, just to implement a drop-down box.
1: https://en.wikipedia.org/wiki/Principle_of_least_astonishmen...
This is one of these things that sounds perfectly logical -- you want all UI components to look and behave the same across all applications and all websites -- but that is more theoretical than practical.
If you built an app that used just what the browser gives you and nothing more, you're leaving so much functionality on the floor. Having more expressive power often makes things simpler -- using more complex UI controls has allowed me to eliminate whole pages from my application. Users are happier and more productive.
Browser UI implementations can't do one thing that is vital: compete.
> As a user, I want common UI controls to look and behave the same way across all web sites.
That ship has sailed. (and I wish it had not)
> Everyone's site looks and feels inconsistent with every other site.
Somehow, this model won. Most people muddle through and figure it all out...
With this kind of take - why do we need different applications at all?
UX/UI is solved just use spreadsheet grid, you can do everything in spreadsheet and you will have exactly the same interface/way of doing things.
It is not a joke - I personally have like 80% of things in a spreadsheet (don't get me started what kind of spreadsheet abuse I have seen in my career). But I do understand that lots of stuff can be done much more efficiently with tailored controls and not everything is couple of drop-downs/text boxes.
Form validation, form elements, search... I've seen far too many sites try to reinvent a browser textarea or edit box, and fail at very basic things because they didn't handle anything they didn't personally think of. (Some common examples: some of the keyboard controls, or correct handling of scrolling when having enough text in the box to scroll, or the interaction between textarea scrolling and page scrolling...)
"satisfactory" is exactly what browsers tend to provide, with a side order of "no surprises". Designers reinvent browser functionality on a theory of "I don't want satisfactory, I want delightful and unique", and sometimes they succeed, but often they fail. As a user, I very rarely want "unique" when it comes to design.
You don't have to be held back by browsers, and you may well be able to do better, but many people who think they can do better end up doing worse.
I don't see what difference it makes whether you use some component built into the browser or some component built on top of the browser.
This article already starts out with how many ways you can screw up this built in browser feature. I bet you didn't even notice that the article examples were slightly broken. The "fix" shows the error when you press submit but doesn't highlight the field in red like if you backspaced it to empty. This is something my validation code does automatically and correctly.
> I don't see what difference it makes whether you use some component built into the browser or some component built on top of the browser.
And this is why you fail. When you use components built into the browser, everyone gets to benefit from the same years of experience and testing, so that edge cases you have never thought about are handled correctly. Websites that re-implement text boxes, history, scrolling, so many things, never get every detail right. They always break on cases the built-in equivalent would handle correctly. Sometimes weird edge-cases, but pretty often completely normal cases that don't appear on the developer's development machine.
> Websites that re-implement text boxes, history, scrolling, so many things, never get every detail right.
As browsers continue to give developers more low-level control, the less of a problem this is. Take one of your examples, history. This used to be a high-level feature implemented only by the browser and if you built an SPA your users either had a very bad experience or you had get "clever" with various tricks. Now, we have a nice history API.
You say that everyone benefits from the same years of experience and testing but at the same time they're limited to a single vendor. A single idea of how it should work. And a single implementation. Right now if I don't like how validation works/looks that is implemented in JavaScript, I can choose any number of alternatives or implement my own ideas.
The browser should help developers build the best possible solutions, it should not implement those solutions itself.
Browsers themselves have always had weird edge-cases and as a web developer I've always had to work around them (see this article). Sometimes even depending on the browser. The whole idea of an "SPA" was never even imagined by browser makers but developers made that happen.
> As browsers continue to give developers more low-level control, the less of a problem this is. Take one of your examples, history. This used to be a high-level feature implemented only by the browser and if you built an SPA your users either had a very bad experience or you had get "clever" with various tricks. Now, we have a nice history API.
Quite the opposite, in my experience! As browsers give developers more low-level control, they're more tempted to build half-assed replacements for built-in functionality.
The history API - it's good it exists, mainly because it gives SPA developers a way to solve one of the many intrinsic flaws in the SPA design. On the other hand, it's subject to ridiculous kinds of abuse (stuffing history to make it appear to users that the back button doesn't work), or getting out of sync (because web developers can't manage a stack) and making history unusable.
> The whole idea of an "SPA" was never even imagined by browser makers but developers made that happen.
Yes, with generally terrible results, which could have been avoided if browsers hadn't stagnated.
> Yes, with generally terrible results,
Really? This is like complaining about movies that use CGI -- you only complain when you can see it. When it's seamless, and often it is, you don't even notice or care.
Why stop at browser apps? All apps are terrible on all operating systems for all the same reasons.
This line of argument seems pretty subjective.
> This article ultimately supports this by showing us exactly how half-baked this particular browser feature happens to be.
In a way, yes. I do think there's a lot to improve from the browsers' side. I guess what I'm trying to say is that the "half baked" solution is also not quite as bad as "no solution" and 1) it can be improved, 2) it really can be used today if you know "how to cook it right"
You say "no solution" like form validation isn't one of the most common things that all web forms do today. Solutions exist. What I'm trying to say is instead of browser building adding high-level functionality like this they should simple continue to provide better ways for us to do it ourselves.
If you code for Windows or Mac OS, you get standard controls, and they do come with a lot of functionality, but ultimately it's still just building blocks for you to build your own functionality. That's what browsers should provide -- low level building blocks.
I totally understand this. Having DOM elements as an entry to some API isn't the best thing.
But firstly, I would consider what you're missing when you abandon native validation
* On submit, the first field that needs attention gets focused automatically
* Error messages for semantic attributes are localized automatically by the browser
* The native message tooltip are actually nice and their placement is handled by the browser. They aren't the best fit for any design system, but for many products they are way nicer than custom implementations.
* Possible styling using CSS pseudo-classes such an ":invalid" or ":user-invalid"
In the end, I do think that the developers would benefit from a more explicitly exposed API for this. Just like we got the "new URL()" constructor, but earlier we had to create an anchor node, fill in its "href" attribute and then read the anchor properties to get to the parts of the parsed URL.
> On submit, the first field that needs attention gets focused automatically
That is long solved.
> Error messages for semantic attributes are localized automatically by the browser
Assuming I want to use their error messages. I would prefer to provide my own, more detailed, error messages. Also what good is localized error messages in a non-localized form?
> The native message tooltip are actually nice and their placement is handled by the browser.
I definitely don't like the placement of the tooltip nor do I even like using tooltips for showing error messages. I much prefer permanently keeping the error message displayed under the field until the user edits the field.
I make some pretty large forms in my job with a lot of complex validation rules and non-technical users. We do validation way better than this.
Strongly disagree. There are so many places where the browser itself provides a reasonably good user interface, and web developers fuck it up - scroll hijacking and history manipulation being two of the biggest examples. I suspect that one of the reasons we ended up in JS-hell is that HTML and browser built-in functionality lagged behind user expectations for so long. If browsers had offered the equivalent of AJAX and DOM element replacement early on, heavy use of JS might never have caught on.
(Consider Triptych [https://github.com/alexpetros/triptych] as the baseline for what browsers should have been providing since 2005 or so.)
The browser only reluctantly accepts its role is an application UI platform. Every problem, including the ones you describe, come from the disconnect between what a browser is and what it is used for. The browser is always going to lag behind user expectations so that's why I think it's the last place we should put that functionality.
Adding more high-level UI functionality is really in conflict with the idea of browser as platform. Other features, like WASM, are pushing the browser the other way.
No it isn’t. It fucking sucks. Most everyone who learns HTML comes across the validation attributes, the god awful built in date pickers and other shit, and they throw it out in favour of custom built better UX implementations. Maybe in the past we would have been clueless because, well, they didn’t exist, but today they do. And they’re junk.
Call spade a spade. Don’t call it heavily underused.
It's extremely frustrating to me how reliably the anti-JS crowd on HN promotes this sort of "just use HTML / CSS" content. Having a general purpose programming is obviously beneficial for application development. There is no arguments to not use Javascript besides "some users (ie the people here on HN and virtually no one else) don't like to enable Javascript"
The last example is bad. You shouldn't scream at your users before they even had a chance to enter the required information so the second password field should not be marked red until the user either is done entering text there (onblur) or tries to submit the form.
That's totally true! Invalid states shouldn't be shown sooner than necessary
It's just that for the demos in the article it makes sense to show invalid states as soon as possible, but for a nicer UX in real apps you need to take into account "touched" and "submitted" states for the form and per input
For the demos I wanted the reader to know at a glance when our validation code takes effect and this obviously comes at a conflict with demoing a fully "real-world" behavior
This is one of my big gripes - when apps are trying to get ahead of me with validation or submission. When I'm entering a 2fa code, I don't need a big red error telling me that the code must be 5 digits before I'm even finished. Worse is when they immediately auto-submit upon entering the last digit, so if I made a mistake I can't backspace and correct it
this is just react though. it's not HTML validation.
The HTML is created using JSX, that's true. But the validation that the browser performs is part of the HTML behavior.
That's nice, I'll use that next time. Although it always feels kind of bad to write client side validation code because you're going to have to do the same checks on the server side anyway.
I find it sad that so many frameworks leave the developer to duplicate server-side and client-side validation. There are obviously some things you can't reasonably validate on the client, but I'd like to see more automated ways to take backend constraints and check them on the client too.
Ideally constraints would also propagate from model definitions, so there could be a single source of truth for "what phone numbers do we accept". Some years back I tried to do this by parsing SQL table definitions, but never got far enough. Django does this, but it lacks pretty much any client-side validation support IIRC. (Or client-side anything, really...)
One of the compelling reasons to use Javascript-based frameworks like nextjs or remix.run is that you can reuse the same logic + types on the frontend and backend.
With Typescript, this is now my preferred way to build full-stack sites.
Do you make your users do a server round-trip to see what's wrong? To have good UX, you kind of have to do both.
You could use something like json-schema to define constraints, and use json-schema validator libs on the front and back end to validate the form data against the schema.
You still need to handle the "what happens next" part on each side, but at least your validation rules are shared.
Necessary because a user can always inspect > modify the HTML.
Why is that bad? Both have uses: 1. Client-side validation is for immediate feedback for the user. 2. Server-side validation is to block malicious actors
> Using other input attributes that create constraints, such as "pattern" or "maxlength"
No. Don't use the maxlength attribute.
https://adamsilver.io/blog/dont-use-the-maxlength-attribute-...
That's great advice!
I also dislike the "character rejection" mechanisms, even though many people love it and products often ask to implement it.
To add to the possible solutions mentioned in your article, I'd add the "pattern" attribute. You can do something like this:
<input pattern=".{0,6}" />
This will allow input of any length, but show a warning then the value is longer than six characters.
Built-in validation is pretty much the only reason I use forms.
Capturing input with frameworks is much simpler than pulling the values out of an event object, so I'd be okay with just using input and button elements.
Yet, that doesn't trigger the validation, so I end up wrapping it with a form element and using a submit button.
> Yet, that doesn't trigger the validation, so I end up wrapping it with a form element and using a submit button.
I run the validation manually using `reportValidity()` on `element.querySelector(...)` before passing it on to whatever.
Do we finally have a standard solution for input masks ? 25 years ago I was struggling with this while my fellow desktop app devs had good input masks in their widgets, with easy to use pattern syntax. That would be embarrassing if not.
Every other website or program now uses a different set of UI patterns. We are not advancing, we are regressing.
I do miss when textboxes had inset and buttons had outset borders.
Guilty. Recently, when I was involved in a project that required a lot of attention to forms, I ended up overlooking the importance of basic simplicity. I regret it a bit. Thanks for sharing your perspective.
Are we seriously talking of HTML by using React examples? The article doesn't even explicitly aknowledge the fact that it is written within the context of react.
A lot of HTML features are underused with everything being done in JS libraries now rather than using built in functions.
In React I just use Formik and Yup to make forms painless. I've yet to discover a better way.
i'm not seeing the custom validation messages in these examples at all in Chrome. Others are?
That's weird! Have you tried submitting the forms in the examples? The custom messages are supposed to be shown in the native browser validation tooltips. The support for those is quite good! Even on mobile browsers
Yup. If it's just me, I guess it's some plugin I have installed or something.
everything html offers more exotic than playing text leaves a bad taste in the month thanks to bad implementations.
yeah i can mark a field as numeric... but then when a phone renders the number only input all popular keyboards will also leave out every single clipboard buttons and helpers. url where you can also search if you type a phrase? too bad you just lost all typing correcting and prediction. it's lame and hopeless.
[flagged]