Consumer Obligations
apps/docs/src/content/docs/accessibility/consumer-obligations Click to copy apps/docs/src/content/docs/accessibility/consumer-obligations Some WCAG AAA success criteria are partially applicable to a component library: HELiX exposes the surface (an attribute, a slot, a token, an event) and the consumer application fulfills the substantive obligation (the autocomplete value, the heading hierarchy, the help-text content, the timeout policy). This page is the explicit handshake. Each section below names a partial-applicability SC, the contract HELiX provides, and the example a consumer ships to close the conformance gap.
At a glance
Section titled “At a glance”WCAG 2.2 · 7 SCs with consumer obligations.
- 7 SCs where the obligation crosses the component/consumer boundary — component exposes, consumer fulfills
- 44 P0 components are AAA-certified end-to-end against the 11 cert criteria (
packages/hx-library/aaa-verdicts.json) - The remaining AAA SCs are content-creator obligations (sign language, reading level, pronunciation, audio description) and fall outside any component-library scope
Why partial applicability is honest
Section titled “Why partial applicability is honest”Component vs. application boundary.
A component library cannot single-handedly ship AAA conformance. WCAG defines accessibility against a web page, not a button or a dialog in isolation. For the seven SCs below, HELiX’s contribution is real but partial: we expose the API, you populate it. Calling these “done” without naming the consumer’s share would be marketing — so we publish both ledgers. If a consumer ships a HELiX-based product without fulfilling these contracts, the page is not AAA, even if every component is.
See the Self-certification scope page for the 11 AAA + peer-standards criteria HELiX measures on its P0 surface, and the VPAT 2.5 conformance report for the per-criterion ledger.
1.3.6 Identify Purpose
Section titled “1.3.6 Identify Purpose”AAA · partial · consumer fulfills.
What WCAG 2.2 1.3.6 requires (user-agent identifies purpose):
In content implemented using markup languages, the purpose of UI components, icons, and regions can be programmatically determined. This lets assistive tech and personalization tools surface the right meaning (e.g. recolor “cancel” vs “submit”, replace icons with words, autofill a name field correctly).
What HELiX provides (component contract):
hx-text-input exposes the native autocomplete attribute directly — it forwards through to the internal <input> so the browser-level autofill machinery sees a normal autocomplete declaration. Other form components (hx-textarea, hx-select, hx-combobox, hx-date-picker, etc.) do not currently expose a public autocomplete attribute — populating them requires either a future API addition or a consumer-side workaround (rendering the field’s internal input directly, or layering autocomplete through a wrapping form). Buttons and links accept the standard aria-label / accessible-label attribute for semantic intent beyond the visible text. Icons use hx-icon’s label attribute (renders as aria-label plus a <title> inside the SVG).
What you fulfill (consumer code):
Populate autocomplete on every hx-text-input whose purpose matches Section 7’s input-purpose tokens. For other form-component types, file a tracking request or fall back to a native input until the API lands. A signup form should look like:
<hx-text-input name="given-name" autocomplete="given-name" label="First name"></hx-text-input><hx-text-input name="family-name" autocomplete="family-name" label="Last name"></hx-text-input><hx-text-input name="email" type="email" autocomplete="email" label="Email"></hx-text-input><hx-text-input name="tel" type="tel" autocomplete="tel-national" label="Phone"></hx-text-input>1.4.8 Visual Presentation
Section titled “1.4.8 Visual Presentation”AAA · partial · consumer fulfills.
What WCAG 2.2 1.4.8 requires (user-controllable presentation):
For blocks of text, the user can:
- Select foreground and background colors
- Limit width to 80 characters or less
- Avoid full justification (no fully-justified text)
- Set line-spacing to at least 1.5 within paragraphs
- Set paragraph spacing to at least 1.5x line-spacing
- Resize text to 200% without horizontal scroll
What HELiX provides (component contract):
hx-prose defaults to a relaxed line-height (var(--hx-line-height-relaxed)) and constrains body width via --hx-prose-max-width (default 720px — under the 80-char ceiling for normal-size body text). Text alignment is start by default; HELiX never emits text-align: justify. Color tokens (--hx-prose-color, --hx-color-surface-default) are user-overridable at the semantic tier — set them once on the consumer’s root and every component recolors via cascade. Per-component customisation hooks exposed by hx-prose: --hx-prose-max-width, --hx-prose-font-size, --hx-prose-line-height, --hx-prose-color, --hx-prose-heading-color, --hx-prose-link-color.
What you fulfill (consumer code):
Do not override hx-prose defaults to make text denser. If you do override typography globally, preserve the line-height and paragraph-spacing minimums via the prose tokens. Do not apply text-align: justify to body content.
/* OK: narrow the measure (stays under the 80ch ceiling) */hx-prose { --hx-prose-max-width: 60ch;}
/* OK: adjust prose typography while preserving AAA minimums */hx-prose { --hx-prose-line-height: var(--hx-line-height-loose);}
/* NOT OK: forces line-height below the 1.5 floor */hx-prose::part(content) { line-height: 1.2 !important;}
/* NOT OK: full justification fails 1.4.8 */hx-prose::part(content) { text-align: justify;}2.2.4 Interruptions
Section titled “2.2.4 Interruptions”AAA · partial · consumer fulfills.
What WCAG 2.2 2.2.4 requires (user can suppress):
Interruptions (alerts, banners, toasts, system notifications) can be postponed or suppressed by the user, except interruptions involving an emergency.
What HELiX provides (component contract):
hx-toast exposes open (boolean), duration (number, default 5000ms), closable (boolean) and variant ('default' | 'success' | 'warning' | 'danger' | 'info'). hx-banner and hx-alert accept dismissible to render a close affordance and open to control visibility. prefers-reduced-motion: reduce automatically pauses motion across hx-toast, hx-banner, hx-carousel, and any timed transition.
HELiX does not ship a global interruption-suppression mechanism today (no persistent attribute, no data-hx-no-interruptions document-level switch, no emergency queue bypass). Suppressing non-emergency notifications based on a user preference is consumer-application work: gate the call site that would otherwise create the toast.
What you fulfill (consumer code):
Wire a user-controllable preference (settings page, OS-level preference) into your toast-creation call sites. Keep emergency-priority signals (variant="danger" with explicit consumer routing) outside the suppression gate.
// Consumer settings UI toggles this flagconst interruptionsSilenced = getUserPreference('silence-non-emergency-toasts');
function showRoutineToast(message) { if (interruptionsSilenced) return; // queued/dropped at the call site const toast = document.createElement('hx-toast'); toast.variant = 'info'; toast.duration = 3000; toast.open = true; toast.textContent = message; document.body.appendChild(toast);}
function showEmergencyToast(message) { // Emergency signals bypass the user-preference gate const toast = document.createElement('hx-toast'); toast.variant = 'danger'; toast.closable = true; toast.duration = 0; // 0 = no auto-dismiss toast.open = true; toast.textContent = message; document.body.appendChild(toast);}2.2.6 Timeouts
Section titled “2.2.6 Timeouts”AAA · partial · consumer fulfills.
What WCAG 2.2 2.2.6 requires (user warned of data loss):
Users are warned of the duration of any user inactivity that could cause data loss, unless the data is preserved for more than 20 hours when the user does not take any actions.
What HELiX provides (component contract):
hx-dialog exposes modal, open, heading, description, and close-on-backdrop (default true). To prevent backdrop-dismissal during a critical interaction, set close-on-backdrop="false". hx-toast exposes duration + closable for the inverse case (notifications that should not auto-disappear: pass duration="0"). The library does not impose session timeouts — those are the consumer application’s concern.
HELiX does not ship a persistent attribute on dialogs or toasts; that name does not exist in the CEM. To make a dialog non-dismissible, set close-on-backdrop="false" and handle Escape suppression in your own keydown handler (HELiX does not currently expose an escape-disabled switch).
What you fulfill (consumer code):
Surface a warning before any session-timeout-driven data loss. Use hx-dialog with modal + close-on-backdrop="false" + a countdown to give the user a chance to extend, save, or discard.
<hx-dialog modal close-on-backdrop="false" heading="Your session is about to expire" id="session-timeout"> <p>You will be signed out in 2 minutes. Unsaved changes to this patient record will be lost.</p> <hx-button slot="footer" variant="primary" onclick="extendSession()">Stay signed in</hx-button> <hx-button slot="footer" variant="ghost" onclick="saveDraftAndSignOut()"> Save draft and sign out </hx-button></hx-dialog>2.4.10 Section Headings
Section titled “2.4.10 Section Headings”AAA · partial · consumer fulfills.
What WCAG 2.2 2.4.10 requires (content structure):
Section headings are used to organize the content. Headings should follow a logical hierarchy (no skipped levels) and describe the section that follows.
What HELiX provides (component contract):
hx-prose renders consumer-supplied <h1>–<h6> with the correct visual hierarchy and clear margin rhythm, but it does not auto-determine heading levels — that is the consumer’s page-structure decision. hx-text is a typography primitive with variant (body, body-sm, body-lg, label, label-sm, caption, code, overline) and an as attribute ('span' | 'p' | 'strong' | 'em' | 'div'); it does not expose a level attribute or render heading elements — for visual heading-like text that is not part of the outline, use hx-text with a styling variant inside a non-heading element, or author a real heading. Component slots like hx-card[slot="heading"], hx-dialog’s heading attribute, and hx-drawer[slot="heading"] accept any heading element so the consumer chooses the level.
What you fulfill (consumer code):
Author your page’s heading hierarchy explicitly. Do not skip levels. Reach for hx-text only for non-outline typography; use real heading elements for the outline.
<main> <h1>Patient overview</h1>
<section> <h2>Vitals</h2> <hx-card variant="featured"> <!-- Card heading IS part of the outline → real h3 in the heading slot --> <h3 slot="heading">Heart rate</h3> <hx-stat value="72 bpm"></hx-stat> </hx-card>
<hx-card variant="featured"> <!-- Decorative label not in outline → hx-text label variant --> <hx-text slot="heading" variant="label" as="span">Last reading</hx-text> <hx-format-date date="2026-05-07T08:31:00Z"></hx-format-date> </hx-card> </section>
<section> <h2>Active medications</h2> <!-- ... --> </section></main>3.1.4 Abbreviations
Section titled “3.1.4 Abbreviations”AAA · partial · consumer fulfills.
What WCAG 2.2 3.1.4 requires (expansion available):
A mechanism for identifying the expanded form or meaning of abbreviations is available. In practice this is the <abbr title="…"> element on first use, or a glossary linked from the page.
What HELiX provides (component contract):
hx-prose styles native <abbr> with a subtle dotted-underline affordance and surfaces the title via the browser’s native tooltip plus aria-label when consumers attach one. hx-tooltip provides a richer surface for explanations longer than a single phrase (slots: default and content). The library does not own content — we do not auto-detect abbreviations.
What you fulfill (consumer code):
Wrap every abbreviation in <abbr> on first occurrence per page or per section. For domain-heavy content (medical, legal), maintain a glossary route the abbreviation links to.
<hx-prose> <p> Patient presents with elevated <abbr title="Blood Pressure">BP</abbr> (148/96) and tachycardic <abbr title="Heart Rate">HR</abbr> at 112 bpm. Order <abbr title="Electrocardiogram">ECG</abbr> stat. </p></hx-prose>
<!-- For a richer explanation, hx-tooltip wraps the abbr; the abbr is the trigger (default slot) and the explanation goes in the content slot. -->
<hx-tooltip> <abbr title="Glasgow Coma Scale">GCS</abbr> <p slot="content"> A 15-point scale used to assess level of consciousness. 15 = fully alert, 3 = deep coma. Scored on eye, verbal, and motor responses. </p></hx-tooltip>3.3.5 Help
Section titled “3.3.5 Help”AAA · partial · consumer fulfills.
What WCAG 2.2 3.3.5 requires (context-sensitive help):
Context-sensitive help is available for any component that requires user input. For forms in regulated contexts (legal, financial, medical), help should explain what the input is for and the format expected.
What HELiX provides (component contract):
Every form component (hx-text-input, hx-textarea, hx-select, hx-combobox, hx-checkbox-group, hx-radio-group, hx-date-picker, etc.) accepts a help-text attribute (HTML) / helpText property (TS) and a help-text slot for richer markup. The component renders the help text in a labelled region inside its shadow root and references its ID from the internal input’s aria-describedby so the help text is announced after the field label by every screen reader. hx-help-text is a standalone primitive for cases where you need the help-text styling outside a form component. hx-tooltip + hx-popover surface longer explanations on demand. Field-level hx-field-label renders the required-marker and links the label-input pair via Shadow DOM-internal for/id.
What you fulfill (consumer code):
Populate help-text with substantive content — what the field is for, the format expected, and where to find more information. Do not leave help text empty on compliance-critical fields.
<!-- OK — substantive help that meets 3.3.5 --><hx-text-input name="ssn" label="Social Security Number" autocomplete="off" required> <span slot="help-text"> Format: 9 digits, no dashes (e.g. 123456789). Used only to verify insurance eligibility — not stored on this device. </span></hx-text-input>
<!-- For long-form help, hx-popover surfaces the explanation on demand -->
<hx-text-input name="advance-directive" label="Advance directive on file?"> <hx-popover slot="help-text"> <button type="button" aria-label="What is this?">?</button> <p slot="content"> An advance directive is a legal document specifying your healthcare wishes if you cannot communicate them yourself. See the <a href="/help/advance-directives">advance-directive help page</a> for details. </p> </hx-popover></hx-text-input>Cross-references
Section titled “Cross-references”Related ledgers.
- Self-certification scope — the 11 AAA + peer-standards criteria HELiX measures end-to-end on its P0 surface, plus the formal-audit harness and gating policy.
- VPAT 2.5 conformance report — the per-criterion conformance ledger published with each release.
- Keyboard Contracts (Storybook) — per-component keyboard interaction matrix. Complements 2.4.3 Focus Order and 2.4.7 Focus Visible.
- Focus Management (Storybook) — focus delegation, restoration on dialog/drawer/popover dismissal, and the focus-ring token contract.