Bring Focus to the First Form Field with an Error :: Aaron Gustafson
A handy little script from Aaron to improve the form validation experience.
A handy little script from Aaron to improve the form validation experience.
A neat little tool when you need a reminder about what elements can go in other elements.
Just like brand values, mission statements, or vision decks, design principles can be generic and provide little to no actual value.
But used correctly, design principles help you make decisions resulting in a superior experience.
Be liberal in what you accept:
Basically, if your form can’t register Beyoncé – it has failed.
Six steps that everyone can do to catch accessibility gotchas:
- Check image descriptions
- Disable all styles
- Validate HTML
- Check the document outline
- Grayscale mode
- Use the keyboard
The slides from a presentation by Drew on all the functionality that browsers give us for free when it comes to validating form inputs.
Half the battle of the web platform is knowing what technology is out there, ready to use. We’re all familiar with the ability to declare validation constraints in our HTML5 forms, but were you aware there’s a JavaScript API that goes along with it?
How a certificate with extended validation makes it easier to phish. But I think the title could be amended—here’s what’s really broken:
On Safari, the URL is completely hidden! This means the attacker does not even need to register a convincing phishing domain. They can register anything, and Safari will happily cover it with a nice green bar.
Like Lighthouse, but from Microsoft.
Dave uses just a smidgen of JavaScript to whip HTML5’s native form validation into shape.
Instead of being prescriptive about error messaging, we use what the browser natively gives us.
Good question! And a good answer:
If you really need it, which you probably don’t,
readonly
is what you want.
An interesting idea from Ruth—using subtle sounds to augment inline form validation.
There aren’t any extremely established best practices for this stuff. The best we can do is make tasteful choices and do user research. Which is to say, the examples in this post are ideas, not gospel.
Form validation taken to the extreme. If you want to know more about how it was done, there’s an article explaining the markup and CSS.
A few straightforward steps for improving the usability of credit card forms. The later steps involve JavaScript but the first step uses nothing more than straight-up HTML.
I saw Christian speak on this topic at Smashing Conference in Barcelona. Here, he takes a long hard look at some of the little things that sites get wrong when doing validating forms on the fly. It’s all good sensible stuff, although it sounds a bit medical when he takes about “Premature Inline Validation.”
This is a truly fantastic example of progressive enhancement applied to a form.
What I love about this is that it shows how progressive enhancement isn’t a binary on/off choice: there are layers and layers of enhancements here, from simple inline validation all the way to service workers and background sync, with many options in between.
Superb!
Stuart’s ideas for Lighthouse sound a lot like the resilience validator tool that Scott mentioned recently.
This is our chance to help stamp out sites that don’t do things right, and help define that a progressive web app should actually be progressive.
If you have ideas on this, please file an issue.
If you have a manifest.json file for your site, here’s a handy validator.
This is my go-to method for adding validation messages to forms—I think I first heard about it from Derek—so it’s nice to see it corroborated by Steve:
Add the error message as a child of the label element associated with an input.
I like CSS pseudo-classes. They come in handy for adding little enhancements to interfaces based on interaction.
Take the form-related pseudo-classes, for example: :valid
, :invalid
, :required
, :in-range
, and many more.
Let’s say I want to adjust the appearance of an element based on whether it has been filled in correctly. I might have an input
element like this:
<input type="email" required>
Then I can write some CSS to put green border on it once it meets the minimum requirements for validity:
input:valid {
border: 1px solid green;
}
That works, but somewhat annoyingly, the appearance will change while the user is still typing in the field (as soon as the user types an @ symbol, the border goes green). That can be distracting, or downright annoying.
I only want to display the green border when the input is valid and the field is not focused. Luckily for me, those last two words (“not focused”) map nicely to some more pseudo-classes: not
and focus
:
input:not(:focus):valid {
border: 1px solid green;
}
If I want to get really fancy, I could display an icon next to form fields that have been filled in. But to do that, I’d need more than a pseudo-class; I’d need a pseudo-element, like :after
input:not(:focus):valid::after {
content: '✓';
}
…except that won’t work. It turns out that you can’t add generated content to replaced elements like form fields. I’d have to add a regular element into my markup, like this:
<input type="email" required>
<span></span>
So I could style it with:
input:not(:focus):valid + span::after {
content: '✓';
}
But that feels icky.
Update: See this clever flexbox technique by Kitty Giraudel for a potential solution.
When I was talking about Async, Ajax, and animation, I mentioned the little trick I’ve used of generating a progress
element to indicate to the user that an Ajax request is underway.
I sometimes use the same technique even if Ajax isn’t involved. When a form is being submitted, I find it’s often good to provide explicit, immediate feedback that the submission is underway. Sure, the browser will do its own thing but a browser doesn’t differentiate between showing that a regular link has been clicked, and showing that all those important details you just entered into a form are on their way.
Here’s the JavaScript I use. It’s fairly simplistic, and I’m limiting it to POST requests only. At the moment that a form begins to submit, a progress
element is inserted at the end of the form …which is usually right by the submit button that the user will have just pressed.
While I’m at it, I also set a variable to indicate that a POST submission is underway. So even if the user clicks on that submit button multiple times, only one request is set.
You’ll notice that I’m attaching an event to each form
element, rather than using event delegation to listen for a click
event on the parent document and then figuring out whether that click
event was triggered by a submit button. Usually I’m a big fan of event delegation but in this case, it’s important that the event I’m listening to is the submit
event. A form won’t fire that event unless the data is truly winging its way to the server. That means you can do all the client-side validation you want—making good use of the required
attribute where appropriate—safe in the knowledge that the progess
element won’t be generated until the form has passed its validation checks.
If you like this particular pattern, feel free to use the code. Better yet, improve upon it.