Contextual Help
A contextual help is a small help button — often a question-mark glyph — that opens a popover with explanatory content for a nearby field, control, or concept.
Use it next to labels and headings where users may need extra explanation on demand without cluttering the primary UI. The help content is hidden by default and revealed only when the user requests it.
Implementation Notes
- Uses a
<div>wrapper with classcontextual-help - The trigger is a
<button class="contextual-help-trigger" type="button">witharia-haspopup="dialog" expandedreflects open state on the trigger viaaria-expanded- The trigger references the panel via
aria-controls={panelId} - The panel is a
<div class="contextual-help-panel" role="dialog">and is hidden via thehiddenattribute when closed - The panel id is generated stably via
useId,crypto.randomUUID, or a Math.random helper
Props
label: string (required) -- aria-label for the help trigger buttonexpanded: boolean (defaultfalse) -- whether the popover is openonClick/onclick: callback (optional) -- trigger click handlerchildren: slot -- popover content...restProps: any additional HTML attributes
Usage
<ContextualHelp
label="Help for username"
expanded={open}
onClick={handleToggle}
>
<h3>Username</h3>
<p>Use 3-20 characters. Letters, numbers, and underscores only.</p>
</ContextualHelp>
Keyboard Interactions
- Tab / Shift+Tab: Move focus into and out of the trigger and panel
- Enter / Space: Activate the trigger to toggle the popover
- Escape: (Consumer-provided) close the popover when open
ARIA
- Trigger:
aria-label,aria-haspopup="dialog",aria-expanded,aria-controls={panelId} - Panel:
role="dialog",id={panelId},hiddenwhen closed
When to Use
- Use to add optional explanatory content next to a field, label, or concept
- Use when help should not occupy persistent space in the layout
- Use when the help is short and self-contained
When Not to Use
- Do not use for required instructions — show those inline as
Hinttext - Do not use for blocking confirmations — use
DialogorAlertDialog - Do not use for guided tours — use
CoachmarkorTour
Headless
Renders a <button> trigger and a <div role="dialog"> panel linked by aria-controls. Open/close state, positioning relative to the trigger, animation, and visual treatment are entirely the consumer's responsibility.
Styles
Consumer CSS targets the contextual-help wrapper, contextual-help-trigger button, and contextual-help-panel panel classes. Provide a clear focus indicator on the trigger and ensure the panel is reachable by keyboard.
Testing
- Verify the wrapper renders a
<div>with classcontextual-help - Verify the trigger renders a
<button>witharia-label={label} - Verify the trigger has
aria-haspopup="dialog" - Verify
aria-expandedon the trigger reflectsexpanded - Verify
aria-controlson the trigger matches the panel id - Verify the panel renders with
role="dialog"and the matching id - Verify the panel uses
hiddenwhenexpandedisfalse - Verify the panel id is stable
Advice
- Designers: Use a recognizable help affordance (e.g., a question mark in a circle); do not rely on color alone.
- Developers: Generate panel ids server-side or with
useIdto remain hydration-stable.
Related components
tooltip— a small popup showing descriptive text on hover or focuspopover— a floating content box anchored to a trigger elementdetails— a disclosure widget that shows and hides content
References
- WAI-ARIA Dialog: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
- Adobe Spectrum Contextual Help: https://spectrum.adobe.com/page/contextual-help/
- WCAG 1.3.1 Info and Relationships: https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships