Don’t Disable Form Controls

Just another usability and accessibility pro telling authors not to do the thing they continue to do.

It’s Ok to Disable Buttons

A pair of metal toggle switches, each with a red plastic guard that prevents accidentally flipping the switch and which can be lifted to expose the switch.
There are plenty of cases where you want to disable a button until a user takes a conscious action to enable it, such as when launching nuclear missiles.

Telling authors not to disable buttons is too broad. There are cases where it’s appropriate to disable something controlled by a button. Buttons can do lots of things — expand disclosures, pop dialogs, play videos, toggle themes, slide views, download files, and so on — and disabling the button may be a least-bad method of signaling a feature is not currently available but may be later for reasons that you have made clear to the user.

Whether or not you want to do that is a function of context, audience, expectations, and more. Often there are better ways to handle making a feature inactive, but a blanket ban is not ideal.

Don’t Disable Submits

The place where buttons should not be disabled is within the context of submitting a form. Or, more specifically, within the context of gathering information from a user that may need to go through validation, review, corrections, and so on. This includes platforms that rely on asynchronous connections to move data around instead of HTML forms.

When you hear a usability, user experience, accessibility, research, or interface design professional warn you not to disable buttons, they are generally talking about submit buttons.

I don’t need to make that case. Plenty of folks have written about it (in my opinion they aren’t aggressive enough):

When a self-professed UX expert argued that submits could be disabled, his comments filled up asking for evidence why the author chose to contravene a well-known usability principle (for which he offered only combativeness). Those comments reinforce why disabling submits is bad.

Don’t Disable Form Fields

Telling authors not to disable submit buttons is too narrow. Authors should not disable any form fields.

Default styles are a terrible signal a field is disabled. Authors trying to make obvious disabled styles often leave users unable to either see a field at all or distinguish it from the other fields on the page. Rarely do authors explain why users cannot interact with a disabled field.

Disabling fields is no replacement for good instructions and error messages. Having a “clean” page is pointless if users cannot figure out how to get past it. You might as well lock them in a padded white room and paint a door on the wall.

Never mind cases where a form field isn’t even necessary, let alone a disabled one that demonstrates how little experience the development team has with humans around the world.

Those of us who have worked with users already know from experience that authors often do a poor job of conveying why a a user cannot submit, that styles rarely convey this well, that users get confused, and that WCAG is less useful because disabled controls exempt contrast requirements.

Disabling Decision Tree

I made a quick decision tree to help evaluate when it’s acceptable to disable interactive controls:

  1. Is the control part of a form?
    1. No.
      • Maybe don’t disable it, but test with your users.
    2. Yes.
      • Don’t disable it.
  2. See Step 1.

Wiggle Room?

I have an absolutist take on this. Not because it should never happen, but because the barrier for an author doing it should be sufficiently high as to warrant exploring all other options first. Only after those are all exhausted, to then consider rebuilding the thing so a disabled control is not the only option. If that is still the case, then user testing and evidence and signatures and blood pacts should come into play.

This burden should always be on the author, not the user. If you find yourself blaming the user for the pattern you built, you might be bad at your job.

Read-Only Is Not a Solution

Buttons are read-only controls. There is no good reason to make a submit button read-only. That’s just acknowledging they should not be disabled. Let’s not pave a cow path that results in so much confusion.

As for other form controls being read-only, well, that’s a topic for another ranty post.

8 Comments

Reply

Hi Adrian,

Thank you for the insightful article on why we shouldn’t disable form controls. Your points are well taken and underscore the importance of maintaining usability and accessibility in web design.

I’m reaching out to share a challenge we often encounter at Zenyth, particularly when working with platforms like Webflow and BigCommerce. In these environments, form validation scripting is typically controlled by the platform itself, which can result in less-than-ideal user experiences. For example, on Webflow, we’ve noticed that attempting to submit a form before completing validation triggers intrusive alert messages.

Our workaround has been to disable the submit button until all form fields are validated, re-enabling it only when the form is ready for submission. This approach, while not ideal, has been our best solution to ensure a smoother user experience under these constraints.

Given your expertise, we’d greatly appreciate any suggestions for alternative strategies that align with best practices in accessibility while addressing the limitations imposed by such platforms. Our goal is to create the most accessible and user-friendly websites possible, even within the constraints of third-party platforms.

Thank you for your time and consideration. Looking forward to any insights you might have.

Best regards,

Crystal Scott, CPWA
Web Accessibility Engineer, Zenyth

In response to Crystal Scott. Reply

Crystal, that indeed sounds like a challenge. My only experience with Webflow and Big Commerce is that they are de facto accessibility barriers as platforms. However, I have no idea if the scenario you pose is genuinely intrusive, is configurable, is itself a pile of WCAG failures, and so on.

As long as your workaround is only a workaround, then clients need to understand why and what risk (legal or otherwise) the platforms are assigning them. But then you have, in my opinion, a responsibility to go further.

File bugs with Webflow. Teach your clients to file and follow up on those bugs. Demand ACRs. Document on your site what the problems are with those platforms. List the WCAG failures. Share this information broadly. Teach the community what questions to ask and what commitments to expect.

Essentially put these platforms on notice that you are aware, that their clients are at risk, that you have a quick hit list for for fixes (which, sadly, can be used by drive-by lawyers to file suits), and so on. Some organizations only act when something risks their revenue stream.

In other words, the code you write is a stop-gap. The real work now is not code, but pushing for change.

Reply

Hey Adrian,

Thanks for the write-up. I have a question surrounding how best to handle situations where we genuinely want to prevent users from interacting with parts of a form for brief periods of time, for example, to prevent the user from entering race conditions while a server-side computation is running. Here’s a concrete example:

I run a hotel reservation service that has a form with a checkbox for “smoking” vs “non-smoking” rooms. When the user interacts with the checkbox, an updated price and availability check (that only the server knows) must be reflected in the form. In order to prevent the user from entering a race condition (i.e. clicking the checkbox 20 times and then submitting the form), we want to prevent certain user interactions, including toggling checkbox state / submitting the form.

It should also be said that during this time, the user would be fully appraised on what’s happening via aria-live mechanisms.

Thoughts on this scenario? Is disabling form elements in some fashion or another recommended here?

Thanks!

In response to Luke. Reply

Luke, disabling the control would cause the focus to be lost. That is not good.

You could try the approach I use on my post Multi-Function Button. It was put into use by a few of my clients, including a large US bank, so I have some confidence it is not terrible.

In response to Adrian Roselli. Reply

Hi Adrian,

I checked out your example. That’s a pretty neat pattern. My only comment is that it did seem a bit confusing that I could select “Success (sandwich)”, then tab and activate the button, then shift+tab back to the radio and switch the option to “Failure (no sandwich)” and get the failure result without re-activating the button. In other words, if a user changes their mind after triggering the button, there isn’t any indication to the user that the updated option has been accepted by the computation process.

To sum things up for UX / designers, the overall recommendation is to not expect developers to tap into events like change or keypress to initiate server-side computations, but in all cases provide all end-users with a dedicated button elements to initiate the events, such that the UX workflow is to make a selection, then activate a button to start the computation? Or is it recommended not to run any server-side computations until the user actually submits the form? Does this pattern look the same with multiple computation triggers on a form?

As always, thanks for your guidance.

In response to Luke. Reply

Luke, my example is targeted at developers so they can adjust the outcome at any time. I would not do that in a screen facing end users. How you choose to account for an analogous real-life scenario will be a function of your audience, your instructions, how the system can handle post-submit changes, and so on.

To sum things up for UX / designers, the overall recommendation is to not expect developers to tap into events like change or keypress to initiate server-side computations, but in all cases provide all end-users with a dedicated button elements to initiate the events, such that the UX workflow is to make a selection, then activate a button to start the computation?

I am struggling to understand this question because it is complex, nested, relies on assumptions (that on their own could fail WCAG, such as 3.2.2), and uses the absolute “all”. Regardless, generally forms as I have defined them in this post should have submit buttons.

Or is it recommended not to run any server-side computations until the user actually submits the form?

To big-word this, that question is orthogonal to the point of this post. Server-side computations can happen in nifty AJAXy ways (like filtering in a type-ahead field). I don’t know all possible scenarios you have in mind. Just don’t disable the submit button.

Does this pattern look the same with multiple computation triggers on a form?

Oh — you’re asking about the sandwich button in the other post. Good question. I have no idea what you are thinking, which is why I think it is a good question for you to work out with the use cases I outlined and your own user testing.

Reply

One bit of advice I would have in any situation in which a widget is disabled: please, please explain in your UI why the widget is disabled. I have been working in UI/UX in some capacity for around a decade at this point, and disabled buttons, inputs, etc. are universally confusing if no explanation exists in the UI. Whether the button is a submit button, or whether the input is part of a form, is irrelevant to the confusion. Users will always try to click on disabled widgets, and if they’re disabled with no context, it causes immense frustration. Designers and front-end engineers, please include an accessible explanation in your UI if you do choose to disable something.

Shannon; . Permalink
In response to Shannon. Reply

Emphatically upward-pointing finger emoji, Simpsons yellow skin color.

Assuming the dear reader has opted to ignore my advice, of course.

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>