from a usability perspective, the pattern of using <button disabled> states for form validation causes cognitive overload because users have to infer the validation requirements of a form.
an appropriate use of <button disabled> is when an active <button> changes temporarily <button disabled> when some action is being processed (e.g., image uploads, payment verification) that should block the submission of the form.
use the browser's built-in HTML5 form validation (e.g., <input required>). clicking on an always-active <button type="submit"> in a <form> validates all fields w/ constraints and will present the user with native error messages. (the error strings can be customised but not the styles.)
- add text hints contextually near the fields that are
(Optional)vs.(Required). if most fields are required — so as to not clutter the UI and desensitise with distracting(Required)text everywhere — use(Optional)text when needed and have the user assume the lack of implies(Required). - override the rendering of the browser's error messages when the user clicks on the
<button type="submit">Next</button>, and then display a custom error message (ideally, contextually inline or, if the error involves multiple fields, at the top of the form).
- in the case of one-field forms with single
<input type="radio">(not<input type="checkbox">), conditionally hide a<button type="submit">until a selection is made.
from the bible on form design (Best Practices for Form Design)(https://static.lukew.com/webforms_lukew.pdf) by usability expert LukeW:
additionally, there appears to be somewhat of a consensus here based on a usability study:
Don’t ever disable the submit button and only show validation errors after the user hits submit.
The always-active button [is the better solution].
Why?
With an always-active button, you can select it, and then be told what isn't complete.
With an inactive button, you are stuck. You may not know why it's inactive and as such, hit a dead end.
Inactive buttons are incredibly annoying. There's no indication as to why they are inactive providing no way for the user to figure out how to activate
more:
If the form is still invalid when clicking submit you could auto scroll to show them (if they've get "out of the screen") and show the errors below the fields until each field is modified. This approach is currently used by Google, Facebook and Twitter.
In case you want to disable the submit button, you MUST at least show a message next to it giving the reason why it's disabled because if you don't it could cause confusion to the users. Anyway I don't recommend it, remember in that case you are supposing the user is thinking (and thinking correctly) "one step ahead", which is a really bad UX design practice.

