Why this matters
As a Data Visualization Engineer, you often display insights in charts, dashboards, and tables. Tooltips help explain data points; tables present dense information. If these arenât accessible, keyboard and screen-reader users canât get the same insights. This subskill helps you build tooltips and tables that are usable for everyone.
- Real tasks youâll face: clarifying chart values with tooltips, adding help text to icons, building sortable tables, making dense pivot tables understandable.
- Impact: fewer support tickets, better compliance, broader audience reach, and more trustworthy analytics.
Who this is for and prerequisites
Who this is for
- Data Visualization Engineers building dashboards, reports, and embedded analytics.
- BI developers who implement tables, grids, and chart interactions.
Prerequisites
- Basic HTML and CSS.
- Awareness of ARIA attributes (what they are and when to use them).
- Basic keyboard accessibility knowledge (focus, tab order).
Concept explained simply
Tooltips are short descriptions that appear on user demand (focus, hover, or activation). For accessibility: the trigger must be focusable, the tooltip content must be reachable by assistive tech, and any critical information must not live only in the tooltip.
- Trigger: a focusable control (usually a button). Provide an accessible name.
- Association: connect the trigger to the tooltip using
aria-describedby. - Tooltip: element with
role="tooltip", shown on hover/focus, hidden otherwise. - Dismissal: when possible, make it dismissible (e.g., Escape) and not trap focus.
Tables are for structured data with headers. Screen readers rely on correct semantics to announce the cellâs header context.
- Use semantic HTML:
<table>,<caption>,<thead>,<tbody>,<tfoot>,<th>,<td>. - Simple tables: set
scope="col"for column headers andscope="row"for row headers. - Complex tables (multi-level headers): use
idon header cells andheaderson data cells. - Sorting: use a button inside the header and reflect state with
aria-sort.
Mental model
- Tooltips: think âhint attached to a control.â If the user can focus the control, they should get the hint (via focus/description). If the hint is essential, also show it somewhere visible so users who canât hover still get it.
- Tables: think âgrid of facts with coordinates.â Every data cell should be traceable to its headers so the user always knows what the number means.
Worked examples
1) Accessible tooltip for an icon-only button
Goal: a keyboard-focusable button with a tooltip that appears on hover/focus and is announced by screen readers.
<div class="tooltip-wrap" style="display:inline-block; position:relative">
<button aria-label="More info" aria-describedby="tip-1">â</button>
<span id="tip-1" role="tooltip" style="position:absolute; left:100%; top:0; margin-left:8px; background:#222; color:#fff; padding:6px 8px; border-radius:4px; font-size:12px; line-height:1.2; visibility:hidden; opacity:0; transition:opacity .15s">
Explains what this control does.
</span>
</div>
<style>
.tooltip-wrap:hover [role=tooltip],
.tooltip-wrap:focus-within [role=tooltip] { visibility: visible; opacity: 1; }
</style>
Why it works: the button is focusable and named; aria-describedby links the tooltip text; hover/focus shows it for sighted users.
2) Help text for form fields (donât rely on hover)
Prefer persistent help when information is essential to complete a task.
<label for="threshold">Threshold (ms)</label>
<input id="threshold" type="number" aria-describedby="threshold-help" />
<div id="threshold-help">Used to flag slow queries. Typical range: 200â1000.</div>
Why it works: The help text is always available and referenced via aria-describedby. No dependency on hover-only tooltips.
3) Simple sortable data table
<table>
<caption>Top queries by average latency (ms)</caption>
<thead>
<tr>
<th scope="col">Query</th>
<th scope="col" aria-sort="ascending">
<button type="button" aria-label="Sort by Avg latency, ascending">Avg latency</button>
</th>
<th scope="col">P95 latency</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Daily active users</th>
<td>240</td>
<td>620</td>
</tr>
<tr>
<th scope="row">Revenue by region</th>
<td>310</td>
<td>800</td>
</tr>
</tbody>
</table>
Why it works: semantic structure, clear caption, proper header scopes, and a clear sorting control with state via aria-sort.
How to build accessibly (step-by-step)
- Make the trigger focusable: use a button for tooltip triggers; for tables, ensure all interactive controls are focusable.
- Name the control: give icon-only buttons an accessible name via text or
aria-label. - Associate help: connect triggers/fields to help text with
aria-describedby; give tooltipsrole="tooltip". - Show on demand: reveal tooltips on hover and focus. Use CSS
:focus-withinor JS. Avoid hover-only behavior. - Ensure fallback: if text is essential, display it persistently or provide a visible help block.
- Table semantics first: use proper headers (
scopefor simple tables;headers/idfor complex). - Sorting state: reflect sort with
aria-sorton the active header and provide keyboard-usable sort buttons. - Test it: keyboard only, then with a screen reader, then with zoom up to 200%+.
Exercises
Do these now. Everyone can take them; progress is saved for logged-in users.
-
Exercise 1 â Add an accessible tooltip to an icon button
Task
Convert an icon-only control into a focusable button with a tooltip announced to screen readers. Show it on hover and focus.
<!-- Start --> <div class="wrap"> <span class="icon">â</span> </div> -
Exercise 2 â Fix the table semantics
Task
Rewrite a div-based table into a semantic table with a caption, header scopes, and a sortable column.
<!-- Start --> <div class="table"> <div class="row head"><div>Country</div><div>Orders</div><div>Revenue</div></div> <div class="row"><div>USA</div><div>120</div><div>$21k</div></div> <div class="row"><div>Germany</div><div>80</div><div>$13k</div></div> </div>
Self-check checklist
- Can you Tab to every tooltip trigger and see the tooltip on focus?
- Does a screen reader announce the control and its description?
- Is essential information visible without requiring hover?
- Does your table have a caption that explains the data?
- Do headers announce correctly when moving cell-by-cell?
- Does sorting reflect via
aria-sortand work with keyboard?
Common mistakes and how to self-check
- Tooltip-only critical info: Fix by making critical info visible or duplicated in persistent help.
- Using the
titleattribute as the tooltip: Many screen readers ignore or treat inconsistently. Use explicitaria-describedbyandrole="tooltip". - Non-focusable triggers: Replace spans/divs with buttons/links.
- Tooltip that traps focus or canât be dismissed: Keep focus on the trigger; dismiss on blur or ESC (if using JS).
- Div-based tables: Replace with semantic table elements.
- Missing header association in complex tables: Use
idon headers andheaderson each data cell. - No sort state: Reflect state with
aria-sortand update it when sorting changes.
Practical projects
- Retrofit: Replace all
titleattributes in a dashboard with accessible tooltips or persistent help. Verify with keyboard and a screen reader. - Sortable KPI table: Build a table with at least 6 columns and implement keyboard sorting on 2 columns. Announce sort state.
- Complex header grid: Create a table with grouped column headers and ensure each data cell references the correct headers.
Learning path
- Start: Focus management and semantics (buttons vs spans, labels and names).
- Then: ARIA basics (
aria-label,aria-describedby,roleusage). - Now: Accessible tooltips and tables (this lesson).
- Next: Interactive patterns (menus, popovers, dialogs) and accessible data charts.
- Always: Test with keyboard and a screen reader.
Next steps
- Audit one existing dashboard and fix at least three tooltip/table issues.
- Document your teamâs tooltip pattern (trigger, naming, show/hide, dismissal).
- Add a test checklist to your PR template for tables and tooltips.
Mini challenge
In under 10 minutes: Make a small 3-column table keyboard-sortable and add a visible caption. If time remains, convert an info icon to an accessible tooltip using aria-describedby.
Hint
- Use a button inside the sortable header and update
aria-sort. - Ensure the icon control is a button with an accessible name.
Quick Test
Available to everyone; only logged-in users get saved progress.