Source: Articles on Smashing Magazine — For Web Designers And Developers | Read More
One of the main laws that applies to almost everything in our lives, including building digital products, is Murphy’s Law: “Anything that can go wrong will go wrong.” Our goal is to prevent things from going wrong and, if they do, mitigate the consequences. In this article, Victor Ponamarev explores different strategies for preventing users from making mistakes.
By definition, an interface is a layer between the user and a system, serving the purpose of communication between them. Interacting with the interface usually requires users to perform certain actions.
Different actions can lead to various outcomes, some of which might be critical.
While we often need to provide additional protection in case users attempt to perform dangerous or irreversible actions, It’s good to remember that one of the ten usability heuristics called “Error Prevention” says:
“Good error messages are important, but the best designs carefully prevent problems from occurring in the first place. Either eliminate error-prone conditions or check for them and present users with a confirmation option before they commit to the action.”
Surprisingly, when we talk about dangerous actions, it doesn’t necessarily mean that something is being deleted.
Here’s an example of a dangerous action from the banking application I use:
The bank approved a loan for me, and as soon as I clicked “Get Money,” it meant that I had signed the necessary documents and accepted the loan. All I have to do is tap the yellow button, and I’ll get the money.
As a result of an accidental tap, you might end up taking a loan when you didn’t intend to, which is why this action can be considered significant and dangerous.
Therefore, a dangerous action does not necessarily mean deleting something.
Some examples may include the following:
There are many methods to prevent users from losing their data or taking irreversible actions unintentionally. One approach is to ask users to explicitly confirm their actions.
There are several ways to implement this, each with its own pros and cons.
First of all, we should understand the difference between modal and non-modal dialogs. It’s better to think about modality state since dialogs, popups, alerts — all of these might be presented either in the modal state or not. I will use the term dialogs as a general reference, but the keyword here is modality.
“Modality is a design technique that presents content in a separate, dedicated mode that prevents interaction with the parent view and requires an explicit action to dismiss.”
Modal dialogs require immediate user action. In other words, you cannot continue working with an application until you respond in some way.
Non-modal dialogs, on the other hand, allow you to keep using the application without interruption. A common example of a non-modal element is a toast message that appears in the corner of the screen and does not require you to do anything to continue using the app.
When used properly, modal dialogs are an effective way to prevent accidental clicks on dangerous actions.
The main problem with them is that if they are used to confirm routine actions (such as marking a task as done), they can cause irritation and create a habit of mindlessly confirming them on autopilot.
However, this is one of the most popular methods. Besides, it can be combined with other methods, so let’s dive into it deeper.
Use modal dialogs when a user action will have serious consequences, especially if the result of the action is irreversible. Typical cases include deleting a post or project, confirming a transaction, and so on.
It depends on what kind of action users want to take, but the main thing to keep in mind is how serious the consequences are and whether the action is reversible or not.
However, this might not be enough.
In some cases, you may require an extra action. A typical solution is to ask users to type something (e.g., a project name) to unblock the CTA button.
Here are a few examples:
ConvertKit asks users to type “DO IT” when removing subscribers.
Pro tip: Note that they placed the buttons on the left side! This is a nice example of applying proximity law. It seems reasonable since the submit button is closer to the form (even if it consists of only one input).
Resend asks users to type “DELETE” if they want to delete an API key, which could have very serious consequences. The API key might be used in many of your apps, and you don’t want to break anything.
This modal is one of the best examples of following the best practices:
Notice that Resend also places buttons on the left side, just as ConvertKit does.
Note: While generally disabling submit buttons is considered bad practice, this is one of the cases where it is acceptable. The dialog’s request is clear and straightforward both in ConvertKit and Resend examples.
Moreover, we can even skip the submit button altogether. This applies to cases where users are asked to input an OTP, PIN, or 2FA code. For example, the bank app I use does not even have a log in button.
On the one hand, we still ask users to perform an extra action (input the code). On the other hand, it eliminates the need for an additional click.
There is ongoing debate about whether or not to include a submit button when entering a simple OTP. By “simple,” I mean one that consists of 4-6 digits.
While I am not an accessibility expert, I don’t see any major downsides to omitting the submit button in straightforward cases like this.
First, the OTP step is typically an intermediate part of the user flow, meaning a form with four inputs appears during some process. The first input is automatically focused, and users can navigate through them using the Tab key.
The key point is that, due to the small amount of information required (four digits), it is generally acceptable to auto-submit the form as soon as the digits are entered, even if a mistake is made.
On the one hand, if we care about accessibility, nothing stops us from providing users control over the inputs. On the other hand, auto-submission streamlines the process in most cases, and in the rare event of an error, the user can easily re-enter the digits.
For the most critical actions, you may use the so-called “Danger zone” pattern.
A common way to implement this is to either have a dedicated page or place the set of actions at the bottom of the settings/account page.
It might contain one or more actions and is usually combined with other methods, e.g., a modal dialog. The more actions you have, the more likely you’ll need a dedicated page.
Use a Danger Zone to group actions that are irreversible or have a high potential for data loss or significant outcomes for users.
These actions typically include things like account deletion, data wiping, or permission changes that could affect the user’s access or data.
Recently, I discovered that some apps have started using inline confirmation. This means that when you click on a dangerous action, it changes its label and asks you to click again.
This pattern is used by apps like Zapier and Typefully. While at first it seems convenient, it has sparked a lot of discussion and questions on X and Linkedin.
This is for non-critical actions that might be accidentally executed, usually due to a misclick.
There was a concern mentioned by the community of designers regarding the case of users still being able to execute the action by double-clicking.
However, there are three things to consider:
Even though the Jakob’s law says that
“Users spend most of their time on other sites. This means that users prefer your site to work the same way as all the other sites they already know.”
It doesn’t mean that you cannot facilitate the usage of an app by introducing new patterns. Otherwise, the web wouldn’t evolve at all.
I’ve seen attempts to try to fix accidental double-clicking by changing the position of the inline confirmation label that appears after the first click.
But this creates layout shifts. When users work with the app daily, it may cause more irritation than help.
As an option, we can solve this issue by adding a tiny delay, e.g., 100-200ms, to prevent double-clicking.
It also matters who your users are. Remember the good old days when we used to click a dozen times to launch Internet Explorer and ended up with dozens of open instances?
If your target audience is likely to do this, apparently, the pattern will not work.
However, for apps like Zapier or Typefully, my assumption is that the target audience might benefit from the pattern.
This method involves sending a confirmation request, with or without some kind of verification code, to another place, such as:
Notice: I’m not talking about authentication (namely, login process), but rather a confirmation action.
An example that I personally face a lot is an app for sending cryptocurrency. Since this is a sensitive request, apart from submitting the requisition from a website, I should also approve it via email.
It can be used for such operations as money transfers, ownership transfers, and account deletion (even if you have a danger zone). Most of us use this method quite often when we pay online, and our banks send us OTP (one-time password or one-time code).
It may go after the first initial protection method, e.g., a confirmation dialog.
As you can see, the methods are often combined and used together. We should not consider each of them in isolation but rather in the context of the whole business process.
Passkeys are a modern, password-less authentication method designed to enhance both security and user experience.
“Passkeys are a replacement for passwords. A password is something that can be remembered and typed, and a passkey is a secret stored on one’s devices, unlocked with biometrics.”
There are a few pros of using passkeys over 2FA, both in terms of security and UX:
The passkeys are widely supported and more and more companies adopt it.
This is a mechanism when two users are involved in the process. We may call them initiator and approver.
In this case, the initiator makes a request to take some action while the approver decides whether to confirm it or not.
In both roles, a confirmation dialog or other UI patterns may be used. However, the main idea is to separate responsibilities and decrease the probability of a bad decision.
Actually, you have likely encountered this method many times before. For example, a developer submits a pull request, while a code reviewer decides whether to confirm it or decline.
It is best suited for situations when the seriousness of decisions requires few people involved.
There is a direct analogy from real life. Take a look at the picture below:
The Council of Physicians reminds us that in medicine, seeking a second opinion is crucial, as collaboration and diverse perspectives often result in more informed decisions and better patient care. This is a perfect example of when a second opinion or an approver is essential.
Here, you will find some apps that use this method:
But here is the thing: We can consider it a separate method or rather an approach for implementing business logic because even if another person confirms an action, it is still a dangerous action, with the only difference being that now it’s another person who should approve it.
So, all of the examples mentioned above are not exactly a standalone specific way to protect users from making wrong decisions from the UI point of view. It’s rather an approach that helps us to reduce the number of critical mistakes.
When you ask users to take action, you should be aware of its original purpose.
The fact that users make actions does not mean that they make them consciously.
There are many behavioral phenomena that come from psychology, to name a few:
A reasonable question that may arise: What are the alternatives?
Even though we cannot entirely affect users’ behavior, there are a few tactics we can use.
In some scenarios, we can artificially delay the task execution in a graceful way.
One of my favorite examples is an app called Glovo, which is a food delivery app. Let’s have a look at the three screens you will see when you order something.
The first screen is a cart with items you chose to buy (and an annoying promotion of subscription that takes ⅓ of the screen).
After you tap the “confirm order” button, you’ll see the second screen, which asks you whether everything is correct. However, the information appears gradually with fade-in animation. Also, you can see there is a progress bar, which is a fake one.
After a few seconds, you’ll see another screen that shows that the app is trying to charge your card; this time, it’s a real process. After the transaction proceeds, you’ll see the status of the order and approximate delivery time.
Pro tip: When you show the status of the order and visually highlight or animate the first step, it makes users more confident that the order will be completed. Because of the trick that is called Goal-Gradient Effect.
You’ve just paid, and “something starts happening” (at least visually), which is a sign that “Oh, they should have already started preparing my order. That’s nice!”
The purpose of the screen with a fake progress bar is to let users verify the order details and confirm them.
But this is done in a very exquisite way:
In the previous version of the app, you couldn’t even skip the process; you could only cancel it. Now they added the “Continue” button, which is essentially “Yes, I’m sure” confirmation.
This means that we return back again to the drawbacks of classic confirmation modals since users can skip the process. But the approach is different: it’s a combination of a feedback loop from the app and skipping the process.
This combination makes users pay attention to the address, order, and price at least sometimes, and it gives them time to cancel the order, while in the classic approach, the confirmation is “yes or no?” which is more likely to be confirmed right away.
The undo pattern allows users to reverse an action they have just performed, providing a safety net that reduces anxiety around making mistakes.
Unlike confirmation modals that interrupt the workflow to ask for user confirmation, the undo pattern provides a smoother experience by allowing actions to be completed with the option to reverse them if needed.
It works perfectly fine for non-destructive, reversible actions &mdashl actions that don’t have significant and immediate consequences:
Combined with a timer, you can extend the number of options since such tasks as sending an email or making a money transfer could be undone.
It’s not suitable for actions that have serious consequences, such as the following:
The undo option is tightly related to the concept called soft deleting, which is widely used in backend frameworks such as Laravel.
The concept means that when users delete something via the UI, it looks like it has been deleted, but in the database, we keep the data but mark it as deleted. The data is not lost, which is why the undo option is possible since we don’t actually delete anything but rather mark it as deleted.
This is a good technique to ensure that data is never lost. However, not every table needs this.
For example, if you delete an account and don’t want users to restore it (perhaps due to legal regulations), then you should erase the data completely. But in many cases, it might be a good idea to consider soft deleting. In the worst case, you’ll be able to manually restore user data if it cannot be done via the UI for some reason.
There’s something I want everyone to keep in mind, regardless of who you are or what you do.
Every situation is unique. A certain approach might work or fail for a variety of reasons. You might sometimes wonder why a specific decision was made, but you may not realize how many times the interface was revised based on real user feedback.
User behavior is affected by many factors, including country, age, culture, education, familiarity with certain patterns, disabilities, and more.
What’s crucial is to stay in control of your data and users and be prepared to respond when something goes wrong. Following best practices is important, but you must still verify if they work in your specific case.
Just like in chess, there are many rules — and even more exceptions.