Disabled buttons

Alexander Machugovskiy
8 min readJan 29, 2024

--

Always enabled buttons have long been among the “best practices” of UX design, but there are still disabled buttons in interfaces here and there. In 2021, my colleagues at «Open Investments» asked me to make a presentation with a theoretical proof of the “buttons should always be enabled” concept. It’s handy to have an argument on hand to present to the product manager. I have formalized the presentation into an article and hope it will be useful to product designers and product managers as well.

On the left: the handle is active. On the right: handle is inactive, suggest 5 ways to open the door

Buttons purpose

A button is needed to perform the action. If the button is not working, it is impossible to perform the action. Blocking the action is appropriate when there are not enough conditions (or data) to perform the action.

Not enough data

The program can await data from its own components (server, local storage, results of local calculations) or from the user.

The user may not provide data:

  1. on the current screen
  2. at the previous step
  3. on third-party services (like not confirming an email address)

Program components may not provide data:

  1. due to a connection error (slow internet)
  2. because of the long calculations (like key generation)
  3. due to an internal program error

Thus, there are at least 6 possible explanations for why an action is blocked.

The user knows nothing about the program’s inner processes and cannot reliably determine the reason why a button is inactive. The user’s reaction is reduced to the options: “I did something wrong” or “the program does not let me do what I want”. Both options cause negative emotions.

The only option for the user to avoid negative emotions is not to notice the inactive button at all. This is the pattern that designers apply: make inactive elements as invisible as possible.

But that doesn’t help much. Let’s take a look at this layout and compare the variants:

Enabled button:

  1. ✅ Is clearly visible
  2. ✅ Is located in an easy to press location
  3. ✅ Is pressable
  4. ❌ Premature pressing causes an error

Disabled button:

  1. ❌ Is poorly visible
  2. ❌ is located in an easy to press location (but takes it for nothing)
  3. ❌ Is not pressable
  4. ❌ Premature pressing does not lead to anything

A disabled button cannot please the user in any good way. It’s handy only for a designer to reserve space for an enabled button in advance. The designer made his work easier, good for him. But he did not think about the user.

The designer made his work easier, good for him (picture by Nodeus)

Enable buttons!

Let the button be always enabled. The user can try to perform an action at any time. If the attempt is rejected, the interface will inform about the reason — point to the missing data (highlighted in red, for instance). The user will not have to guess what he/she (or the program) is doing wrong.

Hiding the button under scrolling

It’s good if you manage to hide the button at the very bottom, under scrolling — no one will see whether it is enabled or not. When the user fills in all the data and scrolls to the bottom, then he/she will see the enabled button. The principle of timeliness is observed, everything is cool. Let’s compare the variants.

The button is always visible:

  1. ✅ Clearly visible
  2. ✅ Located in an easy to press location
  3. ❌ Takes up content’s space
  4. ❌ Premature pressing causes an error

The button is hidden under scrolling:

  1. ❌ Not visible until you scroll to the end of the page
  2. ✅ Is located in an easy to press location (after all data has been entered)
  3. ✅ Takes up no space
  4. ✅ Premature pressing is unlikely

There are more arguments for the second variant, indeed. So, it’s better to hide the button under scrolling. But in reality, users do not behave ideally. Some scroll down without filling in the data. If such a user sees a disabled button, he/she will face the question: why the button doesn’t work. As we defined above, there can be at least 6 answers. This is an overkill. Therefore, a button hidden under scrolling should also be enabled.

Button location rules

We have understood that the button should always be enabled. Now let’s define the rules of positioning this very enabled button. The “button takes up space” argument stops working on pages with little content. Therefore, the balance of advantages and disadvantages changes depending on the content of the page. In seeking to outweigh advantages over disadvantages, we will arrive at two different rules of thumb: little content — the button is visible, a lot of content — the button is hidden under scrolling.

On the left — content fits on the screen. On the right — content does not fit on the screen.

Little content, visible button:

  1. ✅ Is clearly visible
  2. ✅ Is located in an easy to press location
  3. ✅ Takes up no content’s space
  4. ❌ Premature pressing causes an error

A lot of content, hidden button:

  1. ❌ Is not visible until you scroll to the end of the page
  2. ✅ Is located in an easy to press location (after all data has been entered)
  3. ✅ Takes up no space
  4. ✅ Premature pressing is unlikely

As a designer, it’s easier for me to make one universal appearance: pin the button to the bottom edge of the screen and always show it on top of the content (I showed such a variant above). And it’s easier for the programmer to make one appearance as well. The designer and programmer unwittingly confuse the simplicity of the interface with the simplicity of creating the interface, from which they make up as if their simple solution will simplify the life of the user as well. But the arguments for a universal appearance are easy to refute. Users are comfortable always tapping in the same place, right? Wrong, the users tap in lots of different places on the screen, they don’t care. Do users want to see the main button always in the same place? Yes, they will see the button in the same place when they scroll to the end of the page. And so on.

In the end, everything speaks in favor of the adaptive rule: little content — the button is visible, lots of content — the button is hidden under scrolling.

Disable buttons!

Sometimes a disabled button is still necessary. If a button causes an irreversibly destructive action, it is useful to prevent the button from being accidentally or recklessly pressed. We do not seek to facilitate an action that the user is likely to regret. The user must remove the safety of the gun before shooting his/her foot.

At the beginning of this article, I wrote about “best practices”. I have a separate article “UX trends are myth” and I’m going to write another article where I’ll critically examine the “best practices”. Studying trends, I came to the conclusion that there is only one trend — technological progress. A UX designer only uses new technologies to bring the experience of using digital products closer to the real experience, to the mechanism of human perception laid down by nature. Same with best practices — they’re only as good as bringing the digital experience closer to the real thing. Getting closer to reality is the only best practice. In the case of buttons, a simple analogy from the real world comes to mind: if something doesn’t work, it’s broken. If an object does not respond to a touch, then it’s dead.

Conclusion

So, as a result of the above, the following rules should be adhered to:

  1. The button is always enabled
  2. If the conditions for an action are not met when the button is pressed, the interface indicates them
  3. A little content — the button is visible
  4. Lots of content — the button does not overlap the content, it is hidden away under scrolling
  5. Destructive irreversible action — the button is disabled, until the user’s intention is confirmed

How to

Two different appearances can be packed in a single layout. Let me show how I do it in Figma.

First of all, I create a frame the size of my phone screen. Then I put auto layout inside, same size, fixed dimensions, with “left and right” and “top and bottom” constraints. So, as I change the size of the frame (this is useful for testing the design on different screen sizes), I also resize auto layout automatically. I would like to use auto layout without frame, but it can’t be addressed in Figma’s prototypes, so I have to nest it inside the frame.

The left and middle screens are the same, only scrolling position differs

The auto layout contains (from top to bottom) a system status bar, a top element (such as a title or menu), another auto layout for scrollable content, and bottom system menu (such as web browser navigation or keyboard).

For the scrollable auto layout the scrolling behavior should be set to “Overflow: Vertical” on Figma’s “Prototype” tab. I place all the items inside this auto layout, then put a spacer, and then a button. And remember — no vertical gaps between the items!

Spacer is a key. It’s just a transparent rectangle with vertical and horizontal resizing set to “Fill”. A little content — the height of the spacer stretches to fill the free space, a lot of content — collapses to zero.

The spacer pushes the button to the bottom of the screen

Some might argue: why the spacer? You can group all the items except the button into an auto layout and set its vertical resizing to “Fill”, like I did for the spacer.

I personally don’t like to multiply nested entities beyond necessity. The button is on the same hierarchy level as the rest of the elements, so why separate it? Why waste space on the left navigation panel? Why click more to reach the items within an artificially formed group?

Based on my programming experience, I can say that spacer is not a dirty trick, but a common practice in HTML, QT Designer and many other development tools. It’s not represented in Figma as a built-in object, but programmers may use spacer in their work.

So, a spacer will help you avoid unnecessary nested entities and speed up your work.

If you want to see more case studies, check out at manwe.ru

--

--

Alexander Machugovskiy

Fine art school, Moscow Institute of Electronics and Mathematics, Y&R (art-director), Acronis, Open, Ingos, WeavePay (lead product designer)