Problem/Motivation

Tooltips rendered on the front end fail several WCAG 2.1 success criteria:

  1. Not keyboard accessible (WCAG 2.1.1 Keyboard). The trigger element is a plain with no tabindex, so it can never receive keyboard focus — keyboard-only users cannot reach the tooltip at all.
  2. Tooltip never shows on focus. The trigger setting allows only a single value (click, mouseenter, manual, focus, focusin). With any non-focus value the focus trigger is dropped entirely (Tippy.js's own default is mouseenter focus), so even a focusable trigger would not open the tooltip.
  3. Nothing is announced by screen readers (WCAG 4.1.2 Name, Role, Value). The module enables interactive: true by default, and Tippy.js intentionally skips aria-describedby for interactive tooltips (aria.content: 'auto' resolves to null when interactive). As a result VoiceOver/NVDA/JAWS announce nothing when the tooltip opens.
  4. Not dismissible (WCAG 1.4.13 Content on Hover or Focus). There is no way to dismiss the tooltip with Escape without moving the pointer or focus.
  5. Interactive content is unreachable. Interactive tooltips are appended to document.body, so links inside the tooltip content are outside the natural tab order following the trigger.
  6. The "pin icon" mode renders an empty with no accessible name.
  7. No visible focus indicator (WCAG 2.4.7 Focus Visible) for the trigger.

Steps to reproduce

  1. Install the module, add the tooltip button to a text format's toolbar, keep the default settings (trigger: mouseenter, interactive enabled).
  2. Create a node with a tooltip in the body and view it as an anonymous user.
  3. Try to reach the tooltip with the Tab key — the trigger never receives focus and the tooltip never opens.
  4. With a screen reader running, hover the trigger — nothing is announced.
  5. Open a tooltip with the mouse and press Escape — it does not close.

Proposed resolution

Attached patch makes the front-end rendering accessible for every configured trigger value, without any settings schema changes:

  • ckeditor_tooltips_page_attachments_alter(): always append focus to the configured trigger when missing (e.g. mouseenter → mouseenter focus, click → click focus); pass aria: {content: 'describedby', expanded: 'auto'} so Tippy wires aria-describedby/aria-expanded even for interactive tooltips; pass appendTo: 'parent' for interactive tooltips so keyboard users can Tab into links inside the tooltip content.
  • js/ckeditor_tooltips.js: add tabindex="0" to each [data-tippy-content] trigger that is not natively focusable; give the empty "pin icon" span an aria-label from data-tooltip-title (fallback Drupal.t('More information')); add a document-level Escape handler calling tippy.hideAll().
  • css/front-end-minimal.css: add a :focus-visible outline for the trigger.

Remaining tasks

  • Review the patch / convert to MR.
  • Consider whether the settings form should allow multiple triggers (existing @todo in the form) — out of scope here.
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

luk.tc created an issue. See original summary.

luk.tc’s picture

Assigned: luk.tc » Unassigned
Status: Active » Needs review
zipymonkey’s picture

This is working as expected the tooltip text is focusable but the siteimprove accessibility check is throwing the following error "ARIA attribute unsupported or prohibited" because of the `aria-expanded` attribute on the `span.ckeditor-tooltip-text`. I think that the span also needs to be assigned the button role.

mgifford’s picture