w3c / aria-practices

WAI-ARIA Authoring Practices Guide (APG)
https://www.w3.org/wai/aria/apg/
Other
1.21k stars 345 forks source link

Draft tooltip design pattern #128

Open mcking65 opened 8 years ago

mcking65 commented 8 years ago

The tooltip design pattern is at: http://w3c.github.io/aria-practices/#tooltip

It is largely complete. Things to fix include:

Open questions:

mcking65 commented 7 years ago

Fixed editorial issues in commit b1407a8.

wendyabc commented 7 years ago

Yes, please do include guidance on using tooltip vs title attribute.

mcking65 commented 7 years ago

@wendyabc, do you have some specific issues in mind that such guidance should address?

paulwaitehomeoffice commented 7 years ago

This may already be in hand, but the current wording of the keyboard interactions reads as slightly ambiguous to me:

A tooltip is a popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it. It typically appears after a small delay and disappears when Escape is pressed or on mouse out. ... If the tooltip is invoked when the trigger element receives focus, then it is dismissed when it no longer has focus (onBlur). If the tooltip is invoked with mouseIn, then it is dismissed with on mouseOut.

Should pressing Escape always dismiss the tooltip, or only dismiss the tooltip if it was invoked when the trigger element received focus?

carmacleod commented 7 years ago

Yes, please link to the tooltip dialog pattern rather than the non-modal dialog section.

carmacleod commented 7 years ago

Regarding tooltip vs title: at present, I am not aware of any way for a sighted keyboard-only user to see the content of the title attribute (unless they are using an AT). So, one advantage of using a tooltip is that the tooltip can be displayed for keyboard users, either by:

The advantage of automatically opening the tooltip when the element receives focus is that this makes the tooltip very discoverable for keyboard users, but the (big) disadvantage is that keyboard power users very quickly become tired of them, even when there is a delay.

The (big) advantage of providing a keyboard shortcut to open the tooltip is that users can choose when they want more information. The disadvantages are:

carmacleod commented 7 years ago

The first sentence of the tooltip pattern is: "A tooltip is a popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it." The previous comment discusses 2 ways that a tooltip can be displayed for keyboard users:

So I think we should change that first sentence to something more like the following: "A tooltip is a popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it, or when a focused element receives a specific keyboard shortcut to display the tooltip."

ZoeBijl commented 7 years ago

What exactly is the point of having esc close the tooltip if it appears on hover/focus? As it would close when the control that invoked it is no longer hovered or focused (as mentioned in the note under keyboard interaction).

Related thread on Twitter.

carmacleod commented 7 years ago

Regarding having ESC close the tooltip, if a tooltip is shown (and focused) when the user types a keyboard shortcut (such as F1, Shift+F1, or F2), then ESC can be used to hide it.

Alternatively, perhaps any Tooltip that is optionally shown/focused on a keyboard shortcut falls under the jurisdiction of the Tooltip dialog pattern (issue #85), even if it only contains text?

jnurthen commented 7 years ago

Having ESC close the tooltip allows you to close it if it is distracting. For example, if there were a really big tooltip attached to something which obscures some other information you may want to see when filling in a form field.

On Tue, 23 May 2017 at 07:53 Carolyn MacLeod notifications@github.com wrote:

Regarding having ESC close the tooltip https://github.com/w3c/aria-practices/issues/128#issuecomment-299854925, if a tooltip is shown (and focused) when the user types a keyboard shortcut (such as F1 or F2), then ESC can be used to hide it.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/w3c/aria-practices/issues/128#issuecomment-303423804, or mute the thread https://github.com/notifications/unsubscribe-auth/ABpQP5PUcJCVRG41WS5jMhxaeQWzhMjkks5r8vLkgaJpZM4KYHKf .

carmacleod commented 7 years ago

Having ESC close the tooltip allows you to close it if it is distracting. For example, if there were a really big tooltip attached to something which obscures some other information you may want to see when filling in a form field.

Agreed that that would be a nice thing to have. Note that the ESC key would go to the trigger element in that case, and not the tooltip, because according to the spec, "Tooltip widgets do not receive focus."

steverep commented 7 years ago

The below note seems to violate a success criterion being proposed for WCAG 2.1:

If the tooltip is invoked when the trigger element receives focus, then it is dismissed when it no longer has focus (onBlur). If the tooltip is invoked with mouseIn, then it is dismissed with on mouseOut.

See w3c/wcag21#75. There are accessibility reasons for the tooltip to persist while the tooltip itself has mouse hover.

guyhickling commented 7 years ago

The disadvantages are: discoverability of the keystroke that will open the tooltip (standardization would really help here, but this info can be provided along with other accessibility tips and settings for the site)

The above would be true where an item of content must be clicked on by mouse users to reveal the tooltip text; here the keyboard user would need an F1 or similar shortcut as suggested.

But most tooltips I see involve a separate button beside the content, usually with an icon on them such as a ? character, or an I for information, or even the word Help. Depending on what interactivity the designers have chosen the keyboard user either focusses on it using the Tab key to reveal the tooltip, or they must press Enter or spacebar to reveal it. This kind of tooltip should be allowed for in this SC (I believe they can still be considered tooltips, as they perform the same function and behave the same way, they are just tooltips on the dedicated button instead of on the content itself).

These cases use the

carmacleod commented 7 years ago

Our use case is a code editor. Users can open a tooltip anywhere in the editor, to show the comment for a method or variable, the detailed text of a compiler error or warning, the details of a breakpoint for the current line, etc. Mouse users can see these tooltips by simply hovering over the function/variable name, error/warning indicator, or breakpoint annotation. Keyboard users need to navigate to the "trigger location" using the arrow keys, and then they can optionally open the tooltip by pressing F2.

Note that the editor itself is the "trigger element", but it has focus the whole time, so focusIn cannot trigger the tooltip(s). It is the caret location that determines which tooltip is shown. It does not make sense to open them automatically when the caret reaches the intended trigger location because that gets incredibly annoying.

If you are familiar at all with the Eclipse IDE, this is the way their code editor works. We used the same technique in our code editor because our Web IDE (Orion) was mostly written by Eclipse devs. :)

An additional "quirk" of this technique is that a mouse user can hover to open a tooltip, and then, if they want it to take focus for whatever reason (some of the tooltips have buttons or links in them, which can be activated with keyboard or mouse), they simply type F2 and we give the tooltip focus. Esc closes it.

One could argue that these are "dialog tooltips" and not "tooltips", or maybe they are a different beast altogether, but the typical mouse experience feels exactly like a tooltip, so we tried to keep the keyboard experience as close as possible.

I could imagine an map or some other complex visualization working in a similar manner - the map has focus, the keyboard user navigates with arrow keys, and any time they want more info on the current location, they type F2 to get a tooltip.

Yaffle commented 6 years ago

the title attributes sets the "aria-labelledby", not "aria-describedby", right? So is there cases for tooltips when aria-labelledby should be used - like for a "toolbar button" (icon+tooltip) ?

craigkovatch commented 6 years ago

I would like to see guidance about whether elements with role=tooltip are intended to contain text-only content, i.e. functionally equivalent to the title attribute.

carmacleod commented 6 years ago

I would like to see guidance about whether elements with role=tooltip are intended to contain text-only content, i.e. functionally equivalent to the title attribute.

I believe the tooltip pattern is intended to contain text-only content, and the tooltip dialog pattern is intended for tooltips with interactive children.

@mcking65 can correct me if I am wrong. If this is correct, then yes, it should be explicitly stated in the pattern doc.

Please see #85 for discussion on the tooltip dialog pattern.

craigkovatch commented 6 years ago

I believe the tooltip pattern is intended to contain text-only content, and the tooltip dialog pattern is intended for tooltips with interactive children.

Thanks @carmacleod! What about formatted text, e.g. bold or italics? Is the differentiating factor "interactivity", or is it closer to "anything that's not a plain string"?

carmacleod commented 6 years ago

@craigkovatch Interactivity is the defining factor. Custom tooltips can contain bold, italics, underline, an icon, whatever, as long as you make sure to put the text equivalent of all the stuff in an aria-describedby on the trigger element.

As soon as you add a button or a link or some other interactive thing, then you need to be marking up a "tooltip dialog".

patrickhlauke commented 6 years ago

i'd suggest, nonetheless, that you should avoid putting complex structured text content (e.g. with headings, bullet lists, etc) in a tooltip, as this will all be announced "in a oner" by AT if it's just associated via aria-describedby. so for anything mildly complex/structured, it'd be best for authors to go for a dialog-style tooltip with an explicit close control, i'd say.

carmacleod commented 6 years ago

Excellent point @patrickhlauke. Agree completely. We'll want that advice added as a note in the tooltip pattern doc. :)

carmacleod commented 6 years ago

So is there cases for tooltips when aria-labelledby should be used - like for a "toolbar button" (icon+tooltip) ?

Good point @Yaffle. A "toolbar button" (or any icon that does not have a visible label) does need a label. The author can use aria-label or aria-labelledby, or alt if they're using an <img>, or even title, to give the icon its label.

The author would also want to give the icon a tooltip (using either title or a custom tooltip) so that sighted folks can figure out what the icon is.

So if the tooltip text and the label are the same (which would be the typical case), then I would think that yes, you would use aria-labelledby to point to the custom tooltip text instead of aria-describedby.

waterplea commented 5 years ago

Having modal tooltip just to display links to more info is a bit harsh. We have tooltips icons inside the input visually (kinda like X button to clear input) — how would I go about tooltips with links? Moving focus from input to tooltip for links and locking it there is clearly not an option.

carmacleod commented 5 years ago

@mcking65, regarding the item in the opening comment: "Should there be any guidance about using tooltip verses title attribute", I think the answer is "yes, definitely". :)

This Warning in the W3C HTML spec for title attribute has some useful words:

Warning! Relying on the title attribute is currently discouraged as many user agents do not expose the attribute in an accessible manner as required by this specification (e.g., requiring a pointing device, such as a mouse, to cause a tooltip to appear excludes keyboard-only users and touch-only users, such as anyone with a modern phone or tablet).

carmacleod commented 5 years ago

@waterplea, I just noticed your question:

how would I go about tooltips with links? Moving focus from input to tooltip for links and locking it there is clearly not an option.

Did you find a solution? I don't know of another way to give a keyboard user access to multiple links in a tooltip (which doesn't mean there isn't another way - just that I don't know of one). If your tooltips only contain one link, then perhaps a shortcut key (maybe Shift+F1?) could follow the link without focusing the tooltip. Not sure how natural that would feel.

Are you familiar with the Eclipse IDE? The java code editor has javadoc tooltips that can contain links. A keyboard user would navigate to the java element they wanted javadoc for, then press the F2 key to open and focus the tooltip. Then they can scroll using arrow keys, or tab to the links. They need to type Escape to close the tooltip. In the screenshot below, the user navigated to the FileReader class, and pressed F2 to see its javadoc. In Eclipse, this feels pretty natural. Definitely a "tooltip dialog", though, and not "just a tooltip", although mouse users don't notice the difference. ;)

screenshot of Eclipse code editor with focused tooltip containing java.io.FileReader class javadoc and "See also:" links

waterplea commented 5 years ago

@carmacleod I ended up implementing shifting focus to the first link by arrow down and then regular Tab/Shift Tab to move over links and out of the tooltip to next/previous focusable element on the page.

mbgower commented 5 years ago

A couple of years ago, @guyhickling wrote:

But most tooltips I see involve a separate button beside the content, usually with an icon on them such as a ? character, or an I for information, or even the word Help. Depending on what interactivity the designers have chosen the keyboard user either focusses on it using the Tab key to reveal the tooltip, or they must press Enter or spacebar to reveal it. This kind of tooltip should be allowed for in this SC (I believe they can still be considered tooltips, as they perform the same function and behave the same way, they are just tooltips on the dedicated button instead of on the content itself).

We're assessing a library and found a number of components all called tooltip, one of which provides this kind of interaction on activation. To me, this isn't a tooltip; it's a button whose sole role is to provide 'additional information/context on demand'.

Yes, that sounds like a tooltip, but I think there are some distinguishing matters:

Your text has wording covered much of this with:

displays information related to an element when the element receives keyboard focus or the mouse hovers over it.

You'll note that the help icon is different.

I'd like to see you add a paragraph to the Tooltip Widget section that clarifies the difference, reading something like:

A tooltip does not require onclick activation of the trigger in order for the tip to be displayed. Such behaviour can be offered via a help icon. A help icon provides onclick context for another element, and is made by using a button with aria-haspopup set to true.

Likewise, another of the 'tooltips' in this library we're exploring is interactive. It is a Frankensteinian assembly allowing any manner of inputs inside. I think the final paragraph somewhat addresses this, but it could use some wordsmithing to something like:

The popup information in a tooltip widget does not receive focus. Where interaction in the revealed information is required, a non-modal dialog can be used to display additional information that contains focusable elements.

mbgower commented 5 years ago

Another suggested modification. Change:

It typically appears after a small delay and disappears when Escape is pressed or on mouse out.

to

It typically appears after a small delay and disappears when the trigger loses keyboard focus or the Escape is pressed, or on mouse out.

I also wondered if "on mouse out" entirely matches the scenario covered by the new https://www.w3.org/WAI/WCAG21/Understanding/content-on-hover-or-focus.html.

venikx commented 5 years ago

Not sure if this is the place for discussions, but I'm wondering how a tooltip is supposed to work when the triggering element is an a disabled state. According to https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_disabled_controls is depends in the context where the Tooltip + triggering element is being used. Does that still hold strongly or do you think it's supposed to behave in a different way?

From the docs it's a bit unclear what the behavior should be. If it should work like https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_disabled_controls, it could be useful to add some link (just like in the tree view section) to highlight it depends on the context of the usage.

StommePoes commented 5 years ago

Tooltips are still confusing. As a developer I don't feel I can use them:

  1. touchscreen users... can only click() the things (I'm ignoring expensive touchscreens with "hover" capabilities for now. None of my budget phones can do that kind of magic). So the tooltip-triggers (must?) also Do Stuff on click(). Like a button. Same with speech-rec unless we expect people to painfully MouseGrid all over pages (srsly?).
  2. Differences between a control with a tooltip vs a non-control (?) with a tooltip (and again how do the latter meet my first point?). I think people are converging on clear guidance between the two, but I'd like that guidance to mention word limits or something. Some things just have a buttload of text and maybe it's more than "just" poor UX but actively making things unusable for certain populations.
  3. Coachmarks (tutorial-style intro thingies which look like tooltips, may have interactives inside (often Next buttons or Ok, Got It! links), and are like onLoad() popup modal dialogs in that there's no trigger. What are coachmarks? non-modal dialogs? tooltips? something else? I was first confronted with these things at a job with "hey we have these things, tell us how to make them accessible." uhhh... Again, I'm not sure if they belong under tooltip guidance or something else, but I never solved that problem. I've since seen them on practically every dashboard I've audited.
  4. Anything that shows stuff (esp possibly lots of stuff) on focus or hover which then has aria-whateveredby means anyone using text-to-speech loses the whole purpose of these things: I mean, the tooltip text wasn't sitting out in the open for all to view for a reason. Clean interface? Only deluge users with "helpful" text when they request it (coga reasons)? But keyboarders don't really choose to reveal the text, as the trigger is in the Tab order, and text-to-speech users would basically hear all the blah-blah-blah the moment they encounter the trigger (this might be one place where not hearing aria-foo when in a browse mode makes things nicer but apparently this depends on the SR and isn't codified anywhere?). If the purpose of the thing is lost and the main benefactors are mouse/pointer users, then should the whole idea be rethought? Should it be considered an anti-pattern like title attributes, and all show-text thingies should require a click (and therefore always be a control)? Going through a toolbar of an application and the name of every button is a whole 2-sentence instruction on how to use the button and what it does is a pain in the butt (even taking in that people can skip stuff and if the instructions are an accessible-description then it doesn't pollute name lists). On the other hand, a complex interface may mean users need to re-ask what the 2-sentence instruction is. Is it not ideal that this happens at the user's request? Tooltips offer this "user requests" to non-magnified pointer users, but kinda not anyone else.

There's also an idea I've had: we talk about offering Esc for users to get rid of pop-anythings whether triggered by hover or focus. Something I've wanted as I trigger popups left and right on interfaces littered with them (like Twitter) while zoomed way way in is the ability to click the actual tooltip/pop-anything itself to make it vanish. For tooltips without any controls inside, this could satisfy the "close without moving the pointer" without requiring the keyboard.

waterplea commented 5 years ago
  1. touchscreen users... can only click() the things (I'm ignoring expensive touchscreens with "hover" capabilities for now.

Literally every touchscreen device for past 2-3 or whatever years triggers CSS :hover on touch and emits mouseenter event, I'm not sure what you are talking about. There are problems with mouseleave but it is easily fixed with some JS.

patrickhlauke commented 5 years ago

Literally every touchscreen device for past 2-3 or whatever years triggers CSS :hover on touch and emits mouseenter event, I'm not sure what you are talking about

@StommePoes means that with the exception of some custom heuristics in iOS/Safari/WebViews, which DON'T send the whole sequence of mouseenter>mousemove>mouseleave>click (with variations) if the the first few events caused a change in the page (e.g. popping up a tooltip), it's not possible to trigger just the focus/hover behavior WITHOUT extra JS

StommePoes commented 5 years ago

@waterplea I can't see any of the tooltips here in this Github reply toolbar without selecting them (and when I select them, I still don't see a tooltip). Of course they also go offscreen as my focus is moved to the textarea and my keyboard opens. This means that, on my affordable Android device, I cannot see tooltips on its touchscreen without calling a click event.

waterplea commented 5 years ago

Are you saying neither of those two examples work on your phones? https://codepen.io/waterplea/full/XWrpWQG Works on my affordable Android device. Kinda surprised second one worked on tap outside. I believe it used to not fire mouseleave event a while back, but it worked now.

StommePoes commented 5 years ago

@waterplea both of those work on tap, and both remove the tooltip when I tap elsewhere (maybe firing mouseleave? I'm not sure, and might depend on the browser). Not being controls, I don't have to worry about activating them when attempting to see a tooltip. Compare with the "B" above this (Github's) textarea though: I can tap it, but cannot see the tooltip, because a tap is still always also a click and so it must activate the control (Firefox Focus/Android Go).

In other words, I cannot "hover" without also clicking. An inert element won't have a click event, but the tooltip design includes both active and inactive triggers, and I find that is a relevant issue on touchscreens (excepting amazeballs things like Surface Books).

Meanwhile on a Surface Book 2, with the pen at least, an actual hover action can be performed without touching the screen, meaning the tooltip on the "B" can be read without activating, on the touch screen. I have seen this on a phone touchscreen before, but nothing like normal phone screens.

waterplea commented 5 years ago

@StommePoes there's a touch gesture to focus/hover without clicking which is a slightly long touch, it works natively for such cases for quite some time on all touch devices I've seen. Admittedly people are not that well aware of it, but overall I don't see the technical limitation for tooltips you speak of.

patrickhlauke commented 5 years ago

@waterplea if you long-touch over text, you get the text selection stuff. if you do it over a link, you get the "open in a new tab" etc dialog.

waterplea commented 5 years ago

Right, that's why you can't just smack a tooltip over anything and expect it to work. There are user-select CSS rules and there's common sense in dedicating elements for tooltips. My point was technical limitations StommePoes brought above are not really there mostly, readers are not gonna hear it once they focus since guides tell we should use delays, touchscreens are only limitation if you have some dropdown menues on hover like some old websites had, tooltips work just fine on touch screen, lengthy tooltips are totally responsibility of UI/UX designer and not the concept itself etc. Focusable content like links inside tooltip is really a limitation and should probably be avoided, but overall tooltips seem like not the hardest idea of accessible web aps.

patrickhlauke commented 5 years ago

maybe it's just my cursory reading, but your comments so far have seemed to constantly just handwave concerns that @StommePoes raised with a "not the hardest idea". yes, if developers really put an effort into how they implement them, AND avoid using them for situations where they're not appropriate, it's all fine. doesn't mean the concerns from a user's perspective are invalid.

waterplea commented 5 years ago

I'm sorry, I didn't mean to come in rude.

zelliott commented 4 years ago

Not sure if this is the place for discussions, but I'm wondering how a tooltip is supposed to work when the triggering element is an a disabled state. According to https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_disabled_controls is depends in the context where the Tooltip + triggering element is being used. Does that still hold strongly or do you think it's supposed to behave in a different way?

From the docs it's a bit unclear what the behavior should be. If it should work like https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_disabled_controls, it could be useful to add some link (just like in the tree view section) to highlight it depends on the context of the usage.

We're also encountering this scenario right now. It's common UX for disabled controls to have associated tooltips explaining why they're disabled. Typically these tooltips appear when the disabled control is hovered upon. Unfortunately, there's no keyboard affordance to triggering these tooltips. Disabled controls aren't typically in the tab order, and thus cannot receive focus.

If the disabled controls are explicitly placed in the tab order, then we can trigger tooltips when the disabled control receives focus. However, we're still stuck if the tooltip contains interactive content... as then we need a way of moving focus to the tooltip itself. At this point, it seems we should be following a modal / non-modal / tooltip dialog pattern for the tooltip, but we're again not sure what the keyboard interaction should look like.

Should "Enter" be used on the disabled control to trigger and move focus to the tooltip? Should some new yet familiar keyboard command such as "Shift+F1" be used to move focus to the tooltip (@carmacleod mentioned something along these lines)? Should we re-work our UI entirely to not allow disabled controls that trigger tooltips with interactive content?

Any guidance on this would be greatly appreciated.

JAWS-test commented 4 years ago

I don't know if that's the best solution, but here's what I would think:

It would be easier to inform on the page without tooltip why certain buttons are disabled.

zelliott commented 4 years ago

Focus the interactive elements within the tooltip as you continue to navigate with the Tab key. Alternatively, an access key can be defined to set the focus in the tooltips. This should then be documented on the page.

We have concerns around placing the tooltip itself in the tab sequence in certain scenarios. Suppose that the disabled control is a menuitem, and it has a tooltip with interactive content. It doesn't make sense for the tooltip to be after the menuitem in the tab sequence because this would conflict with the predefined keyboard interaction of menu/menuitem (i.e. arrow keys between items).

This only leaves the alternative of some "access key" to send focus to the tooltip. This is why I pinged @carmacleod about "Shift+F1". Again, not sure if this "tooltip" follows the tooltip pattern, or the tooltip dialog pattern, or the non-modal pattern, etc...

It would be easier to inform on the page without tooltip why certain buttons are disabled.

This would certainly make our problem go away. :)

a11ydoer commented 3 years ago

Next step was discussed at the APG meeting of May 18, 2021

StommePoes commented 3 years ago

Should we re-work our UI entirely to not allow disabled controls that trigger tooltips with interactive content?

I mean, is it good for users that they need to possibly read a lot of UI instructions or that they may have to really fight an interface to use it? If tooltips in general are practically an anti-pattern, I would think

are an anti-anti-anti-pattern, especially if they're found on controls inside ARIA widgets where ordinary users are already having some trouble figuring out how to interact with them (meaning, while we accessiweanies know how they should work, "normal" (non-dev) people don't). I've seen keyboarders confused by Arrow'd menus. They expect to Tab, even if for that menu it would mean a Thousand Tabs of Death to get through it. Instead of doing their task, they spend a bunch of time trying to figure out how to move through the menu. Although people are more willing to spend time learning an interface if it's more like a regularly-used app than a website.

What might make more sense if there are lots of these on an interface is, if say the disabled controls are inside a toolbar or otherwise grouped, having a separate, dedicated control within that group which could offer a (non)modal dialog explaining all the things, with any necessary interactives (links to more docs or whatever).

craigkovatch commented 3 years ago

an anti-anti-anti-pattern

Wait @StommePoes are you saying that anti-patterns don’t cancel out??

Crap, now I have to redo everything! 🤣

StommePoes commented 3 years ago

Wait @StommePoes are you saying that anti-patterns don’t cancel out??

They do, which is why there's an uneven number in my post. An anti-anti-pattern restores balance in the universe. An anti-anti-anti-pattern creates a maze of twisty little passages into hell.

accdc commented 3 years ago

Hi, To recap as we spoke of during the APG call, in order for a broader discussion of tooltip variations to be documented within the APG, we need to index the primary tooltip types and how they differ. Since I've already done the work in building these in practice, I'll break these out to illustrate the differences and associated caveats with each.

First, as I personally expect for these, all tooltips are never directly focusable, nor do they ever include any active elements. Defining this difference illustrates the difference between a tooltip and a non-modal dialog, both of which have very different requirements for accessibility.

In my experience, there are typically 3 primary tooltip category types, standard tooltips, dynamic error tooltips, and dynamic responsive tooltips. The sub-variations fit within each of these.

Standard Tooltips

Behaviors: Standard tooltips are always directly invoked on the focused triggering element, even if the mechanism for doing so may differ between implementations. Also, when the tooltip is set, it remains static and unchanging for as long as the associated tooltip is rendered, even if the tooltip is animated to appear or disappear. Pressing the Escape key on the triggering element will remove the visual tooltip. All tooltips in general can only be invoked from focusable active elements, and focus should never be forcibly moved away from the triggering element when the tooltip is rendered.

The simplest standard tooltip type consists of a focusable active element that references another element using aria-describedby, which causes the Description property to be set on the focused element in the accessibility tree. As an aside, the aria-description attribute can now be used to do the same thing in all mainstream browsers without having to reference an external element, even though this is technically an ARIA 1.3 addition. This capability is important in some circumstances. E.G. The use of aria-describedby can only reference elements that already exist within the DOM, and AT support degrades rapidly when aria-describedby is dynamically set on an element that already has focus, such as when a tooltip is dynamically created after a time delay such as 1.5 seconds after an element receives focus or is moused over. In contrast, aria-description can be set regardless if the tooltip is rendered in the DOM at the same time.

There are 3 different standard tooltip types demonstrated at: http://whatsock.com/Templates/Tooltips/Internal/

The first tooltip displays a tooltip only after the triggering element is explicitly activated by pressing Enter/Space or by clicking/double-tapping it. The focused element is a toggle, and will dismiss the tooltip if activated again. Pressing Escape will similarly dismiss the tooltip; so too will tabbing away from the triggering element. Mouse users can mouse into and out of the tooltip, or directly click or tap it to dismiss it on touch devices.

The second tooltip is triggered by an edit field, and will do so only when the field receives focus. The same pattern for dismissing the tooltip, however, is available by pressing Escape, tabbing away from the field, or mousing into and out of the tooltip or by clicking or tapping it.

The third tooltip is rendered when the triggering element receives focus or is moused over. In this case, since the tooltip element does not exist in the DOM to be referenced using aria-describedby, the aria-description attribute is set to explicitly set the Description property in the accessibility tree instead, regardless if the tooltip is visually rendered at the same time. It must be noted that aria-description is not supported in IE11, and never will be.

A variation of the above standard tooltip type can often be used to represent static inline form field errors after a form submission, where aria-describedby or aria-description is set on the form field in error before focus is set back to that element, thus causing it to be announced when the field receives focus.

Dynamic Error Tooltips

Behaviors: dynamic error tooltips are never directly invoked on the focused triggering element, but rather, only after focus moves away from the triggering element. Thus, aria-describedby and aria-description can never be relied upon for this purpose. When focus is set back to the form field where the dynamic error tooltip is displayed, the tooltip will automatically disappear to prevent obscuring surrounding content.

Example: http://whatsock.com/Templates/Tooltips/Error%20(Inline)/

In this case, since an explicit description cannot be set, a live region is used instead to announce the error tooltip content when focus moves away from the required form field. The simplest and most unobtrusive way of doing this is to use aria-live="polite", which will cause the error to be announced without interrupting speech and preventing the next field in the tab order from being announced when it receives focus.

At present, this works best in Firefox when using a screen reader like JAWS. Live region support in general is still buggy and not always announced as it should be in mainstream AT/browser combos such as JAWS in Chrome, which is disappointing.

Dynamic Responsive Tooltips

Behaviors: Dynamic responsive tooltips are always directly invoked on the focused triggering element, and change programmatically as the user interacts with the field.

Example: http://whatsock.com/Templates/Tooltips/Help%20(Responsive)/

Though it seems intuitive that aria-describedby or aria-description can be used to handle this, this is only partially true. On desktops and laptops where focus is set on the triggering element, dynamically updating either aria-describedby or aria-description will fire a description_change event in the browser, thus causing the newly referenced content to be announced when the Description property changes in the accessibility tree. However, this will only occur when the Description changes on the currently focused element. As a result, this will not work at all when using a mobile platform like iOS where the act of typing into a virtual keyboard causes focus to be present elsewhere while the Description changes. As a result, it is necessary in this case as well to rely on a live region such as aria-live="polite" to announce the newly rendered tooltip content when it appears, which is also subject to the same drawbacks as described with the dynamic error tooltips.

Hopefully this helps to clarify and break down the main differences a bit.

All the best, Bryan

sinabahram commented 3 years ago

Thanks for this fantastic breakdown. Question, how do you reconcile pressing escape with the fact that screen readers such as Jaws and NVDA, within a forms/focus mode, use this to exit that mode? Does this not mean that an SR user cannot dismiss the tooltip without negatively impacting their form-filling experience? I'm less worried about blind SR users, as they have a rare, but not non-zero need (think demos), to dismiss tooltips, but what about sighted SR users that do have such a need or those using magnification with speech where the above concern still holds?

accdc commented 3 years ago

Unfortunately sighted screen reader users will experience the difference you mentioned, and I haven't found a graceful workaround for that. Basically there is a simple keydown event to detect when Escape is pressed, after which the tooltip is removed. However in the case of screen readers, the AT itself is hijacking the keypress in specific circumstances and does not pass the keystroke through to the focused control, which prevents it from doing what is expected. Some people have tried to overcome this by adding role=application around the control to force the user to stay put, but this is a very bad idea and should never be done for the purpose of hacking a screen reader that is hacking the page right back.