Component Contract
Tooltip
Contextual hover and focus information overlay that provides supplementary descriptions, definitions, and guidance across the CAAT Pension Plan member experience.
Live Demo
Directional Tooltips
Rendered
Tooltip on Icon
Rendered
Your commuted value is shown on your annual statement.
Tooltip on Link
Rendered
Your pension is calculated using your best-average earnings and years of credited service.
HTML Content Tooltip
Rendered
Tooltip Bubble
The rendered bubble appearance. The live tooltips above are injected by Bootstrap on hover/focus; this static instance shows the styled bubble for the Figma export.
Rendered
Code sample
HTML
<!-- Directional tooltip on button -->
<button type="button" class="caat-button"
data-bs-toggle="tooltip" data-bs-placement="top"
title="Tooltip on top">Top</button>
<!-- Tooltip on icon -->
<span class="caat-tooltip" data-bs-toggle="tooltip"
title="Helpful definition text" tabindex="0"
role="button" aria-label="More info">
<i class="bi bi-info-circle-fill caat-tooltip__icon"
aria-hidden="true"></i>
</span>
<!-- Tooltip on link -->
<a href="#" class="caat-tooltip__link"
data-bs-toggle="tooltip"
title="Explanatory text">term</a>
<!-- HTML content tooltip -->
<button type="button" class="caat-button"
data-bs-toggle="tooltip" data-bs-html="true"
title="<strong>Bold</strong><br>Line two">
Hover for details</button>
1. Summary
| Name | Tooltip |
| AEM path | caat/components/tooltip |
| Purpose | Provides supplementary contextual information on hover or focus, such as term definitions, field help text, and abbreviated label expansions. |
| Variants | Directional (top, right, bottom, left) · Icon trigger · Link trigger · HTML content |
| Status | New |
| Dependencies | Bootstrap 5.3.3 Tooltip JS, Popper.js (bundled), tokens.css, tooltip.css |
2. Design Tokens
| Token | Role | Value (reference) |
|---|---|---|
--caat-blue-900 | Tooltip background, arrow colour | #003750 |
--caat-blue-700 | Icon trigger colour, link trigger colour | #0b5a80 |
--caat-blue-100 | Hover highlight (reserved) | #e7f4fb |
--caat-green | Success state accent (reserved) | #55a546 |
--caat-grey-200 | Border / divider (reserved) | #dfe6ef |
--caat-focus | Focus ring on trigger elements | #4D90FE |
--caat-ink | Body text colour | #102637 |
--caat-radius | Border-radius on tooltip container | .75rem |
--caat-font-primary | Font family | Libre Franklin |
3. Authoring Fields
| Field | Type | Required | Notes |
|---|---|---|---|
| Tooltip text | Text / RTE | Yes | Plain text for standard tooltips. RTE enabled when HTML content variant is selected. Max 150 characters recommended. |
| Trigger type | Dropdown | Yes | Options: Button, Icon, Link, Inline element. Determines the wrapping element. |
| Placement | Dropdown | No | Top (default), Right, Bottom, Left. Maps to data-bs-placement. |
| Allow HTML | Checkbox | No | Enables data-bs-html="true". Requires RTE input for tooltip text. |
| Accessible label | Text | Conditional | Required when trigger type is Icon. Populates aria-label. |
4. Validation Rules
| Rule | Severity | Message |
|---|---|---|
| Tooltip text is empty | Error | "Tooltip text is required." |
| Tooltip text exceeds 150 characters | Warning | "Keep tooltip text under 150 characters for readability." |
| Icon trigger missing accessible label | Error | "An accessible label is required for icon-triggered tooltips." |
| HTML enabled but text contains no markup | Warning | "HTML mode is enabled but the content is plain text. Consider disabling HTML mode." |
5. Content Guidance
- Tooltips are for supplementary information only — never place essential content inside a tooltip.
- Keep text concise: aim for one or two short sentences (under 150 characters).
- Use sentence case. Avoid all-caps.
- Do not duplicate the trigger element's visible label.
- For pension-specific terms (e.g., commuted value, credited service), provide a plain-language definition.
- Avoid interactive content (links, buttons) inside tooltips — use a Popover instead.
- Use HTML content tooltips sparingly; bold text and line breaks are acceptable, but avoid complex markup.
6. Semantic HTML
<!-- Icon trigger -->
<span class="caat-tooltip"
data-bs-toggle="tooltip"
title="Definition of the term"
tabindex="0"
role="button"
aria-label="More information about [term]">
<i class="bi bi-info-circle-fill caat-tooltip__icon"
aria-hidden="true"></i>
</span>
<!-- Button trigger -->
<button type="button" class="caat-button"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="Supplementary text">
Label
</button>
<!-- Link trigger -->
<a href="/page" class="caat-tooltip__link"
data-bs-toggle="tooltip"
title="Explanation of linked term">
linked term
</a>
<!-- HTML content -->
<button type="button" class="caat-button"
data-bs-toggle="tooltip"
data-bs-html="true"
title="<strong>Term</strong><br>Explanation">
Label
</button>
7. CSS Contract
| Selector | Purpose |
|---|---|
.caat-tooltip | BEM block wrapper for icon / inline triggers |
.caat-tooltip__icon | Icon trigger element styling |
.caat-tooltip__link | Link trigger element styling (dotted underline) |
.tooltip-inner | Bootstrap override — background, colour, radius, font, max-width |
.tooltip-arrow::before | Bootstrap override — arrow colour matching background |
Key CSS rules
.tooltip-inner {
background-color: var(--caat-blue-900);
color: #fff;
border-radius: var(--caat-radius);
font-family: var(--caat-font-primary), sans-serif;
max-width: 250px;
}
.bs-tooltip-top .tooltip-arrow::before {
border-top-color: var(--caat-blue-900);
}
8. Accessibility
| Requirement | Implementation |
|---|---|
| Keyboard accessible | All trigger elements must be focusable. Icon triggers use tabindex="0". Tooltips appear on focus and dismiss on blur / Escape. |
| Screen reader | Icon triggers require aria-label describing the tooltip content. Icons use aria-hidden="true". Bootstrap adds role="tooltip" and aria-describedby automatically. |
| Colour contrast | White text on --caat-blue-900 background meets WCAG 2.1 AAA contrast (minimum 7:1). |
| Motion | Tooltip fade animation respects prefers-reduced-motion: reduce (handled by Bootstrap). |
| Touch devices | Tooltips are not reliably accessible on touch — ensure critical information is not tooltip-only. |
| Focus visible | Trigger elements display a --caat-focus ring on :focus-visible. |
9. SEO
Transient / structural UI with no indexable content of its own — no SEO markup required. Ensure any content this component wraps or reveals stays server-rendered and crawlable.
10. Analytics
Analytics are captured through the shared data-analytics-component attribute on the component root (emitted automatically) and reported to the central data layer. Event names and payloads follow the organisation's standard analytics schema — defined centrally with the analytics team, not invented per component — so no bespoke tracking is specified here.
11. AEM Notes
- Proxy component — create at
/apps/caat/components/tooltipwithsling:resourceSuperTypepointing to the core tooltip component or a custom HTL template. - HTL rendering — emit the
data-bs-toggle="tooltip",title, anddata-bs-placementattributes server-side. Usedata-sly-attributeto conditionally adddata-bs-html="true". - Client library —
caat.components.tooltip(category). Include the tooltip initialisation JS. Depend oncaat.vendors.bootstrap. - Policy — allow placement selection and HTML toggle per template policy. Default placement: top.
- XSS — when HTML tooltips are enabled, sanitise content through AEM's
XSSAPIbefore rendering in thetitleattribute.
12. Dialog Model
Simplified model — shows field intent and Granite UI resource types, not the literal cq:dialog node tree (e.g. select options are authored as child items nodes).
{
"jcr:primaryType": "nt:unstructured",
"sling:resourceType": "cq/gui/components/authoring/dialog",
"items": {
"tabs": {
"items": {
"content": {
"items": {
"tooltipText": {
"sling:resourceType": "granite/ui/components/coral/foundation/form/textarea",
"name": "./tooltipText",
"fieldLabel": "Tooltip text",
"required": true,
"maxlength": 150
},
"triggerType": {
"sling:resourceType": "granite/ui/components/coral/foundation/form/select",
"name": "./triggerType",
"fieldLabel": "Trigger type",
"required": true,
"items": {
"button": { "text": "Button", "value": "button" },
"icon": { "text": "Icon", "value": "icon" },
"link": { "text": "Link", "value": "link" },
"inline": { "text": "Inline element", "value": "inline" }
}
},
"placement": {
"sling:resourceType": "granite/ui/components/coral/foundation/form/select",
"name": "./placement",
"fieldLabel": "Placement",
"items": {
"top": { "text": "Top", "value": "top", "selected": true },
"right": { "text": "Right", "value": "right" },
"bottom": { "text": "Bottom", "value": "bottom" },
"left": { "text": "Left", "value": "left" }
}
},
"allowHtml": {
"sling:resourceType": "granite/ui/components/coral/foundation/form/checkbox",
"name": "./allowHtml",
"text": "Allow HTML content"
},
"accessibleLabel": {
"sling:resourceType": "granite/ui/components/coral/foundation/form/textfield",
"name": "./accessibleLabel",
"fieldLabel": "Accessible label (required for icon trigger)"
}
}
}
}
}
}
}
13. QA Checklist
- Tooltip appears on hover and on keyboard focus.
- Tooltip dismisses on mouse-out, blur, and Escape key.
- All four directional placements render correctly (top, right, bottom, left).
- Arrow colour matches tooltip background (
--caat-blue-900). - Icon trigger has
aria-labelandtabindex="0". - Link trigger displays dotted underline and correct cursor.
- HTML content tooltip renders bold text and line breaks.
- Tooltip max-width is 250 px; long text wraps correctly.
- Focus ring (
--caat-focus) visible on all trigger types. - Screen reader announces tooltip content via
aria-describedby. - Colour contrast: white on blue-900 meets WCAG AAA (7:1+).
- Cross-browser tested: Chrome, Firefox, Safari, Edge.
- Responsive: tooltips reposition when near viewport edges.
- Analytics events fire on
shown.bs.tooltipandhidden.bs.tooltip.
14. Definition of Done
| Area | Done means |
|---|---|
| Design | Figma component matches this contract. All four directional placements and three trigger types documented with colour tokens. Dark-background tooltip with arrow styling included. |
| Development | AEM proxy component created. HTL template emits semantic HTML per Section 6. CSS uses design tokens exclusively. Tooltip initialisation JS included in client library. XSS sanitisation applied for HTML tooltips. Unit tests pass. |
| QA | All items in the QA Acceptance Checklist (Section 13) pass. Manual accessibility audit completed. Cross-browser tested (Chrome, Firefox, Safari, Edge). |
| Launch | Component deployed to AEM production. Content authors trained on trigger-type selection and accessible-label requirements. Documentation published. Analytics dashboards confirmed receiving tooltip events. |