open-ui icon indicating copy to clipboard operation
open-ui copied to clipboard

How should `interestfor` work on a disabled button

Open mfreed7 opened this issue 6 months ago • 7 comments

An example use case would be a hovercard that explains why the button is disabled. This case should work just fine for mouse users, since you can still hover a disabled button. But disabled buttons aren't focusable, nor are they typically long-pressable. So we need a solution for those users. One option is to make such a disabled button focusable. I'm not sure about the a11y implications of that. For touchscreen users, it might still be "ok" to long-press a disabled button and have something happen?

Other suggestions?

mfreed7 avatar Jun 03 '25 22:06 mfreed7

Just as an fyi https://github.com/openui/open-ui/issues/1002

I would lean towards just not supporting it on disabled buttons, but it's possible there's an alternative approach.

lukewarlow avatar Jun 03 '25 22:06 lukewarlow

If the author wants to disable a button and use interestfor on it, can they just change styles on it to make it look disabled and turn off their own activation behavior for it instead of using the disabled attribute?

josepharhar avatar Jun 12 '25 17:06 josepharhar

it shouldn't work on a disabled control. if a disabled control needs to be identified as to why it's disabled, then invoking it from the disabled control will ensure that many people who aren't using a pointer device won't get that information.

scottaohara avatar Jun 12 '25 17:06 scottaohara

Joey's solution might suffice.

One critical use case here is disabled controls that use a rich tooltip or hovercard to explain why they are disabled. This might be critical information, and all users should be able to access it.

b1tr0t avatar Jun 17 '25 17:06 b1tr0t

If it were really critical then people wouldn’t be using an anti pattern to identify why the element was disabled. They’d either make that information part of the ui, or they wouldn’t disable the control, but when someone attempted to activate it, they’d receive a notification of whatever the issue is.

scottaohara avatar Jun 17 '25 18:06 scottaohara

One potential way to make this reasonable is to augment how disabled works when used in combination with interestfor.

  • Still Reflect aria-disabled as true
  • No longer remove the button from the tabindex
  • Prevent Default the activation behaviour
  • All interestfor behaviour would still work as expected

This way you could provide the explanation to all users (using mouse, keybaord or AT).

Though I'm not sure that actually addresses the concerns Scott mentions. It at least avoids something that only mouse users can use?

lukewarlow avatar Jun 18 '25 12:06 lukewarlow

To make sure it could be read by everyone it’d also need to have its contrast updated on at least hover and focus, and along with Luke’s comment now we’ve now almost completely reverted this to resemble a non-disabled control where someone could have just prevented the activation behavior but provided this interest target.

scottaohara avatar Jun 18 '25 13:06 scottaohara

The Open UI Community Group just discussed How should `interestfor` work on a disabled button, and agreed to the following:

  • RESOLVED: do not support `interestfor` on disabled buttons.
The full IRC log of that discussion <keithamus> masonf: A question that came up: interestfor can be used on a button or link, a common use case is to have a disabled button and the tooltip shows up to tell you why (e.g. checkout is disabled as you haven't filled out details).
<keithamus> masonf: the big issue: allowing interestfor on the button... hover could work but you cannot focus, so no way to activate via just keyboard.
<flackr> q+
<scott> q+
<sorvell> q+
<keithamus> masonf: so the question I had was "we need to make this work", but maybe the question is "should we make this work". There seem to be strong views that we should not do this.
<keithamus> masonf: my view - one of the good reasons for the API - if the right thing is to not support it then it forces developers to grapple with the lack of support, which I'm in favor of
<keithamus> masonf: the other point to bring up - the new option 3.5 or so, for touchscreen but more generally: you have a pseudo element that you put on an element that has interestfor, and generally show it, it appears on things with interestfor that you can use to create an icon or similar to show interest.
<keithamus> masonf: that might be the best way around this: a disabled button and a non-disabled pseudo button
<keithamus> flackr: Most AT devices have a "stop on disabled buttons" feature, so we could treat that as showing interest. That would give them the extra info
<keithamus> flackr: If the correct solution is that we have a tab-stop to show the information we can consider that disabled buttons with interestfor have a tab stop, so it is tabbed to by the keyboard.
<keithamus> ack flackr
<keithamus> scott: I don't see why people do this. It's considered an anti pattern to do this - marking something disabled then does not become part of the contract, but you want it to be focusable so people can traverse it. Let alone accessibility, it doesn't meet the visual requirements. So I want to reiterate, this is not a good idea, so we shouldn't do it.
<keithamus> scott: If we want to have a button which is focusable and does something with interaction then it's not disabled - that's a lie - it has functionality! Just not the functionality that it might otherwise have.
<keithamus> scott: So this enables a pattern which people have been told time and time again not to do
<keithamus> ack scott
<keithamus> sorvell: it seems unnecessary, maybe confusing? Disabled should just be disabled. The starting point of it being the common use case; is that actually true? If it is are there cases of this we'd consider them a reasonable pattern or mistakes, like scott mentions?
<masonf> q+
<keithamus> sorvell: in absence of a really good reason - if you want to say why something is disabled, say that, say it separately.
<keithamus> masonf: there are use cases, Im not sure if there are many, but it happens.
<scott> q+
<keithamus> masonf: is the pseudo element with the button on the side problematic? Is okay to have a disabled button with a non-disabled pseudo element next to it?
<masonf> ack sorvell
<keithamus> ack sorvell
<masonf> ack mason
<keithamus> ack masonf
<masonf> ack scott
<sorvell> q+
<sarah4> q+
<keithamus> scott: We could, but it still comes down to the - now there's a keyboard accessible info thing that says "there's something next to this" that the user can't see or traverse to. "Hey look over there, there's something you cant interact with, here's some information about it".
<flackr> q+
<keithamus> scott: even if we made it keyboard accessible, the pseudo element, or the button, change the styling automatically, default styling... how far could we go to overwrite styles to ensure the disabled thing can be viewed properly. It sounds messy
<keithamus> masonf: The original button, if disabled, making it focusable is a thread where you end up pulling you get to a not-disabled button.
<keithamus> masonf: If there's something like a details relationship, or something, you'd know which element you were talking about, you'd see it was disabled, right?
<keithamus> scott: It depends. If it's just a submit button then maybe that's okay, but a popup on enter with validation errors can be done simply. This is an extra step to do that.
<keithamus> scott: It depends on how important the button is... and how much info pops up... but I just don't know if it's really needed or not.
<keithamus> q?
<masonf> ack sorvell
<keithamus> sorvell: reason to prefer not having the pseudo: it doesn't seem useful enough to warrant it. Also things like fieldsets that are disabled, so that pseudo could be useless there - but also these elements are something we can author ourselves.
<keithamus> sorvell: If it made a totally common case super easy then fine, but it doesn't seem particularly useful
<keithamus> masonf: Users seem to not like this, but developers do. And if we don't provide this and they encounter this issue I worry that developers will end up not using the feature and we're back to square one.
<masonf> ack sarah
<keithamus> sarah4: I also don't like the pseudo element, fwiw. I don't think we should have an out. "We'll make it work and make it accessible because developers won't otherwise" I don't buy. Accessibility is more than just focus. The point of interestfor is that you can make it work on a bunch of devices, but buttons are semantically disabled - can't be
<keithamus> activated with voice control for example
<keithamus> sarah4: so altering things like contrast or focusability might make it work for a subset of people but it won't get you all the other cases. So I think it's a bad idea start to finish
<masonf> ack flackr
<keithamus> sarah4: disabled removes interactivity, this is interactivity.
<sorvell> q+
<scott> q+
<scott> to answer rob's question
<keithamus> flackr: One thing I want to understand, some AT devices stop on disabled buttons and read them - is it bad to give AT the option to give more information about why it's disabled? I guess I wonder why it's bad for AT to stop on disabled buttons?
<keithamus> flackr: some ATs have decided to announce disabled buttons, but this gives them more to talk about the disabled button
<keithamus> sarah4: they're not hidden, they're just not interactive. You can add an aria-describedby on there if you want info that may or may not be exposed.
<scott> q-
<keithamus> sarah4: but for an interaction to work, this doesn't fly
<keithamus> flackr: if you put intertestfor on a disabled button it could give a describedby relation to the thing that would pop up?
<keithamus> sarah4: that's just for screen readers though
<keithamus> flackr: but people with mouse could access it... unfortunately keyboard users couldn't.
<scott> q+
<keithamus> sarah4: this is why we shouldn't do anything. Like touch - it won't work with touch unless we change things there, even for mouse users you'd have to put your mouse over it and keep it there... disabled styles come with expectations about how the user can control them
<keithamus> sarah4: trying to make a disabled button not really disabled all the time is going to present us new problems we're not equipped to solve
<keithamus> sarah4: if it works for some it might create a bunch of future problems, to make disabled controls accessible in the way they're meant to be
<keithamus> sarah4: if someone really really wants it they can make their own thing, fine, it won't be accessible necessarily, but whatever.
<masonf> ack sorvell
<keithamus> flackr: I can understand why devs choose this, little clutter, they don't want to show the user why this is disabled unless the user shows interest in why, but I understand.
<keithamus> sorvell: I agree developers seem to want this but it seems like a bad pattern. Why is it announced by AT? because it's not interactive. That's tied to a specific element but this is a holistic state, tied to the application more.
<masonf> ack scott
<keithamus> sorvell: I hear developers say "I want clicks on this button so I can tell the user why it's disabled" and this is the same thing - an anti pattern
<masonf> q+
<keithamus> scott: to clarify: just because an AT can reach a disabled button - the way the virtual cursor works, it's essentially kind of like a mouse (for a lack of better way to describe it). It's not supposed to be programmatically addressable via the web page. It would set up a weird precedent to do something like the virtual cursor hovering over an
<keithamus> element
<keithamus> scott: that also runs the risk of letting the developer know that the user is using a screen reader.
<keithamus> group: *talks a little about mapping of virtual cursors*
<keithamus> sarah4: this is a rabbit hole we don't need to discuss
<keithamus> scott: eys
<keithamus> s/eys/yes
<keithamus> masonf: Steve mentioned the pattern... I agree it's essentially "global state" - it's not disabled because of the button but because of something else on the page.
<keithamus> masonf: I am always maddened on websites that don't help you with the disabled button. So it's a common frustration from users.
<masonf> Proposed resolution: do not support `interestfor` on disabled buttons. An `::interest-hint` pseudo element might be "ok", but perhaps not great either.
<keithamus> q+
<masonf> ack mason
<keithamus> masonf: the first half of this proposal sounds like the conclusion
<masonf> keithamus: there's a conflation of two things. One: constraint validation, and the other is disabling a button. Developers conflate them, but shouldn't.
<sarah4> q+
<masonf> keithamus: all use cases like "you haven't filled out something" isn't necessarily correct to disable the button. Correct path: have constraint validation on the form.
<masonf> keithamus: why is it useful to disable in the constraint validation case? Notifying the user that constraint validation failed seems weird.
<masonf> ack keithamus
<masonf> ack sarah
<keithamus> masonf: one issue is that the built in constraint validation isn't widely used, for example the popups aren't use-ably stylable.
<keithamus> sarah4: I've done multiple studies on ways to handle forms, including validation and disabled buttons... but everyone hates disabled buttons!
<keithamus> sarah4: on the subject of "having an out". We already have an out - they can use aria-disabled instead of disabled, which makes a focusable disabled buttons. We do this in Fluent for non-terrible reasons, such as ensuring focus is not lost if you're on a button that becomes disabled.
<keithamus> sarah4: So if people want an out, disabled styling via classname, tabindex=-1 if they want it non-tabbable, etc.
<keithamus> masonf: I guess devs like disabled because it's safe?
<keithamus> sarah4: yeah they'd have to not add the onclick event...
<sorvell> q+
<keithamus> sarah4: but if they want to do this, it's maybe easier than rolling their own interestfor
<keithamus> sarah4: so if the main impetus for the pseudo is to save people from themselves maybe there are other ways to do it
<keithamus> masonf: just to clarify we're talking about the second sentence in the proposal?
<keithamus> sarah4: yes. If they use aria-disabled they wont be rolling their own popovers etc, so just their own disabled - which is well trodden
<keithamus> masonf: we added the pseudo for touch screen, to avoid too many interactions, but it seems like it could work double duty for this too
<masonf> ack sorvello
<masonf> ack sorvell
<masonf> Proposed resolution: do not support `interestfor` on disabled buttons.
<keithamus> sorvell: Seems like we've veered into UX issues around disabling buttons more generally. I'm comfortable saying something like "there are plenty of bad UX patterns around disabled buttons". But that's beyond the scope of addressing this wrt interestfor.
<keithamus> +1
<sarah4> +1
<scott> +1
<sorvell> +1
<keithamus> masonf: anything to add?
<keithamus> scott: I agree with Steve, the problem we're trying to solve here is a set of poor choices. To be fair to developers it's not them trying to do this, but they've been given designs that didn't account for these things. It's more of a designer problem
<keithamus> scott: so to add anything to this - we should say "we're not doing this because it's a design bad practice and we shouldn't codify it"
<keithamus> masonf: one of the useful things about adding stuff to the platform is it helps us guide people, we can provide docs and help people learn
<keithamus> scott: Maybe even a console warning when you have a disabled button with interestfor? But that could be legitimate to simply add disabled to an existing interestfor and people shouldn't be told off for _that-.
<keithamus> s/_that-/_that_
<keithamus> masonf: we should definitely document on MDN
<masonf> RESOLVED: do not support `interestfor` on disabled buttons.
<sarah4> there's a semi-legit case where you have a conditionally disabled button and you just don't bother removing interestfor when you disable it (even if you correcty don't intend for it to work while disabled)
<keithamus> \o/
<sarah4> o/\o
<keithamus> Zakim, please leave
<Zakim> leaving. As of this point the attendees have been flackr, dbaron, hdv, scott

css-meeting-bot avatar Jun 26 '25 18:06 css-meeting-bot

Apologies to dig up this thread, but recently wanted to close a billing account in some dashboard and the “Close account” button was greyed out. Upon hovering that button, it showed me a tooltip saying that the account could not be closed because of an incorrect account state (and that incorrect state was expressed somewhere else on the page). As a user, I found this pattern (an interested invoked popover on a disabled button) to be really helpful.

Same thing with a long form and the submit button being disabled. A tooltip saying “The form cannot be submitted because it contains errors” upon hovering that (disabled) button is a helpful reminder to scan the form for invalid fields.

bramus avatar Nov 05 '25 09:11 bramus

Problem is that experience isn't accessible to everyone. Personally I think an embedded message in the page that simply says that above or below the button is an easier way to achieve that pattern?

I think if we ever did decide to allow this pattern we'd need to force the button focusable.

lukewarlow avatar Nov 05 '25 11:11 lukewarlow

Problem is that experience isn't accessible to everyone. Personally I think an embedded message in the page that simply says that above or below the button is an easier way to achieve that pattern?

In an action toolbar there isn't always room to put the message right next to the button, as was the case on the dashboard I was using.

I think if we ever did decide to allow this pattern we'd need to force the button focusable.

That is what I was thinking. Focusable, but not actionable.

bramus avatar Nov 05 '25 12:11 bramus

It doesn’t need to be disabled to do that though.

scottaohara avatar Nov 05 '25 13:11 scottaohara

In an ideal world disabled wouldn't affect focus, it'd just set aria-disabled match :disabled and block activation behaviour but that ship has sailed for buttons.

In lieu of that I think the best approach is to set aria-disabled="true" and then key off that for styling and to intercept activation behaviour, in cases where you want this kind of behaviour.

lukewarlow avatar Nov 05 '25 13:11 lukewarlow

50/50 on the topic of disabled elements being focusable or not. But completely agree with the rest of your comment, luke.

But to again state, the style of this “faux disabled” control would likely need to not match the typical disabled style with poor contrast, since someone should be able to read the label of the button that they then also need to read the message about why it can’t be used right now.

I still maintain that every “valid” use case for something like this could be handled just as well by leaving the button enabled and instead of this sort of anti-pattern, clicking would instead invoke a popup, dialog or message on the page to explain why the expected function is not currently available.

scottaohara avatar Nov 05 '25 13:11 scottaohara