Improve Accessibility Of DonationInfoTooltip Component
Hey guys! Today, we're diving deep into improving the accessibility and mobile support for the DonationInfoTooltip component. This is super important because we want everyone to have a smooth and easy experience when using our platform, no matter how they access it. Let's break down the issues and how we're going to tackle them.
Understanding the Current Issues
The DonationInfoTooltip component, located in src/Donations/Micros/DonationInfoTooltip.tsx, has a few accessibility and mobile-friendliness issues that we need to address. These issues can impact users who rely on assistive technologies like screen readers, as well as those accessing the site on mobile devices.
-
Non-Interactive Trigger: Currently, the component uses a
<span>element as the trigger for the tooltip. The problem with this is that<span>elements are not inherently interactive, meaning they are not focusable by keyboard navigation. For users who rely on keyboard navigation, this makes the tooltip inaccessible. We need to replace the<span>with a<button>element, which is designed for user interaction and is naturally focusable.Why is this important? Keyboard accessibility is a core principle of web accessibility. Users with motor impairments or those who prefer keyboard navigation need to be able to access all interactive elements on a page using their keyboard. Using a
<span>instead of a<button>creates a barrier for these users. -
Missing Click/Touch Support: The component currently only supports hover interactions via
bindHover. This means that the tooltip only appears when a user hovers their mouse over the trigger element. This works fine on desktop, but it's a no-go for mobile devices where there's no hover interaction. We need to addbindTriggerto support tap/click events on mobile devices, ensuring that users can access the tooltip content on touchscreens.Why is this important? Mobile devices make up a significant portion of web traffic. If our tooltips don't work on mobile, we're excluding a large number of users from accessing important information. Touch support is crucial for a seamless mobile experience.
-
Duplicate ID Risk: The component uses a hardcoded
popupId: "donationInfoPopover". This is a big no-no because if we render multiple tooltips on the same page, we'll end up with duplicate IDs. Duplicate IDs can cause all sorts of issues, especially for assistive technologies that rely on unique IDs to identify elements on the page. We need to generate unique IDs using React'suseIdhook to avoid these conflicts.Why is this important? Unique IDs are essential for maintaining the integrity of the DOM and ensuring that assistive technologies can correctly interpret the structure and relationships between elements on the page. Duplicate IDs can lead to unpredictable behavior and accessibility issues.
-
Missing ARIA Attributes: ARIA (Accessible Rich Internet Applications) attributes provide semantic information to assistive technologies, helping them understand the role, state, and properties of elements on a page. The current component lacks proper ARIA attributes like
aria-label,aria-describedby, or others that would help screen reader users understand the purpose of the tooltip. Adding these attributes is crucial for providing a good user experience for screen reader users.Why is this important? ARIA attributes bridge the gap between HTML and assistive technologies. They provide the necessary context for screen readers to accurately convey information to users with disabilities. Without ARIA attributes, screen reader users may miss important details or misunderstand the purpose of interactive elements.
-
Missing Tooltip Role: The popup content of the tooltip doesn't have
role="tooltip". Therole="tooltip"attribute explicitly tells assistive technologies that this element is a tooltip, providing additional context and improving the user experience. Adding this role is a simple but effective way to enhance accessibility.Why is this important? The
role="tooltip"attribute helps assistive technologies identify the purpose of the popup content, ensuring that it is properly announced and interpreted. This is especially important for users who rely on screen readers to navigate and understand web content.
Expected Improvements: Making Things Better
So, how are we going to fix these issues? Here’s the game plan:
-
Replace
<span>with<button>: We'll swap out the<span>element for a<button>. This instantly makes the tooltip keyboard accessible, allowing users to tab to the trigger and activate it with the Enter key.Why this helps: Using a
<button>provides native keyboard support and communicates the interactive nature of the element to assistive technologies. -
Add
bindTriggeralongsidebindHover: We'll implementbindTriggerto handle click and touch events. This ensures that the tooltip works flawlessly on mobile devices and provides an alternative interaction method for desktop users.Why this helps: Adding
bindTriggerensures that the tooltip is accessible on touch devices and provides a more versatile interaction model. -
Generate Unique IDs using React's
useIdhook: We'll use React'suseIdhook to generate unique IDs for each tooltip instance. This eliminates the risk of duplicate IDs and ensures that each tooltip is properly identified by assistive technologies.Why this helps: Unique IDs prevent conflicts and ensure that assistive technologies can correctly associate the tooltip trigger with its content.
-
Add Appropriate ARIA Attributes: We'll add ARIA attributes like
aria-label(to provide a descriptive label for the trigger),aria-describedby(to link the trigger to the tooltip content), and others as needed. These attributes will give screen readers the context they need to accurately convey the tooltip's purpose and content.Why this helps: ARIA attributes enhance the semantic structure of the tooltip, making it easier for screen reader users to understand its function and content.
-
Mark Popup Content with
role="tooltip": We'll add therole="tooltip"attribute to the popup content. This explicitly identifies the content as a tooltip to assistive technologies, further improving accessibility.Why this helps: The
role="tooltip"attribute provides a clear signal to assistive technologies, ensuring that the popup content is correctly interpreted as a tooltip.
Diving Deeper into Each Improvement
Let’s take a closer look at each of these improvements and why they matter so much.
Replacing <span> with <button>
Using a <span> for interactive elements is a common mistake that can significantly impact accessibility. <span> elements are generic inline containers with no inherent semantic meaning or interactivity. When used as a trigger for a tooltip, they don't provide any indication to assistive technologies that they are interactive, and they don't support keyboard focus.
Switching to a <button> element solves this problem. <button> elements are specifically designed for user interaction. They are focusable by default, and they communicate their interactive nature to assistive technologies. This simple change makes the tooltip accessible to keyboard users and provides a better experience for everyone.
Code Example:
// Before
<span>More Info</span>
// After
<button>More Info</button>
Adding bindTrigger for Click/Touch Support
Tooltips that rely solely on hover interactions are inaccessible to users on touch devices. Hover events don't exist on touchscreens, so users have no way to trigger the tooltip. Adding bindTrigger ensures that the tooltip can be activated by clicking or tapping the trigger element, making it accessible on all devices.
This also improves the user experience on desktop, as some users may prefer to click rather than hover to access the tooltip content. Providing multiple ways to interact with the tooltip makes it more user-friendly for a wider range of users.
Implementation Details:
We'll need to ensure that the bindTrigger event handler is properly implemented to show and hide the tooltip content on click or tap. This may involve updating the component's state to track whether the tooltip is currently visible.
Generating Unique IDs with React's useId Hook
Duplicate IDs are a major accessibility issue. When multiple elements on a page share the same ID, assistive technologies can become confused and may not be able to correctly associate elements with their labels or descriptions. This can lead to a frustrating and confusing experience for users with disabilities.
React's useId hook provides a simple and effective way to generate unique IDs within a component. By using useId, we can ensure that each tooltip instance has its own unique ID, eliminating the risk of conflicts.
Code Example:
import React, { useId } from 'react';
function DonationInfoTooltip() {
const popupId = useId();
// ...
return (
<button aria-describedby={popupId}>More Info</button>
<div id={popupId} role="tooltip">Tooltip Content</div>
);
}
Adding Appropriate ARIA Attributes
ARIA attributes are essential for providing semantic information to assistive technologies. They allow us to communicate the role, state, and properties of elements that may not be inherently clear from the HTML alone.
For tooltips, key ARIA attributes include:
aria-label: Provides a descriptive label for the trigger element.aria-describedby: Links the trigger element to the tooltip content.aria-haspopup: Indicates that the trigger element controls a popup.
By adding these attributes, we can ensure that screen reader users have a clear understanding of the tooltip's purpose and how to interact with it.
Code Example:
<button aria-describedby={popupId}>More Info</button>
<div id={popupId} role="tooltip">Tooltip Content</div>
Marking Popup Content with role="tooltip"
The role="tooltip" attribute explicitly identifies an element as a tooltip to assistive technologies. This helps screen readers and other assistive technologies correctly interpret the purpose of the element and provide appropriate feedback to the user.
Adding this attribute is a simple but effective way to enhance the accessibility of tooltips and ensure that they are properly handled by assistive technologies.
Code Example:
<div id={popupId} role="tooltip">Tooltip Content</div>
Context and Related Work
This issue was identified during a code review, and we all agreed it's crucial to address these accessibility concerns. It's part of our ongoing effort to make our platform as inclusive as possible.
Related PR: #519 Comment: https://github.com/Plant-for-the-Planet-org/planet-donations/pull/519#discussion_r2343115246 Requested by: @mohitb35
Conclusion: Why This Matters
Wrapping up, improving the accessibility and mobile support for the DonationInfoTooltip component is a big win for our users. By addressing these issues, we're making our platform more inclusive and ensuring that everyone can access the information they need. These changes not only align with accessibility best practices but also significantly enhance the user experience across all devices.
Remember, accessibility isn't just about compliance—it's about creating a better web for everyone. By focusing on these improvements, we're taking a significant step towards making our platform more user-friendly and accessible to all. Keep up the great work, guys! We're making a real difference here!