Skip to content

fix(a11y): non-color signal for Label required indicator (WCAG 1.4.1)#3439

Merged
bilal-karim merged 5 commits into
mainfrom
a11y/1.4.1-use-of-color
May 29, 2026
Merged

fix(a11y): non-color signal for Label required indicator (WCAG 1.4.1)#3439
bilal-karim merged 5 commits into
mainfrom
a11y/1.4.1-use-of-color

Conversation

@bilal-karim
Copy link
Copy Markdown
Member

@bilal-karim bilal-karim commented May 22, 2026

Summary

Replaces the Label required-field indicator's 6×6 red dot with a red mono asterisk marked aria-hidden="true".

 {#if required}
-  <span class="h-1.5 w-1.5 rounded-full bg-interactive-error"></span>
+  <span
+    aria-hidden="true"
+    class="-ml-1 translate-y-0.5 font-mono leading-none text-danger">*</span
+  >
 {/if}

The previous red dot was indistinguishable from a decorative spacer for users with deuteranopia, protanopia, or achromatopsia. The asterisk pairs the same red affordance with a distinct shape signal, satisfying WCAG technique G14 (using text and color).

Why these specific classes

  • text-danger — proper red text token (red.700 light / red.400 dark). text-interactive-error from the audit's literal proposal turned out to be a no-op for text color (only registered under backgroundColor in the theme plugin), so the asterisk rendered black until this was fixed.
  • font-mono — mono asterisks are larger and more geometrically centered than proportional ones, so the indicator reads as a proper visual symbol rather than a tiny text-style superscript.
  • leading-none — tightens the span's line-box to the character so the parent's flex items-center has a tight box to center against.
  • translate-y-0.5 — small downward nudge (2px) so the asterisk visually aligns with the label baseline rather than sitting above it.
  • -ml-1 — reduces the gap to the preceding label text from 8px to 4px so the asterisk reads as part of the label, not a separate element.

Accessible required-state announcement is unchanged — it comes from the native HTML required attribute (which PR #3432 ensured is forwarded on every input primitive). The visual asterisk is aria-hidden to prevent double-announcement ("Email, asterisk, required, edit text").

Audit context

  • WCAG 2.2 SC 1.4.1 Use of Color (Level A) — Serious severity. Affects every required form field across the product.
  • Issue file: audit-output/issues/1.4.1-label-required-indicator.md.
  • The sibling timeline-graph-status fix (the other 1.4.1 defect) will ship in its own separate PR for independent review.

Test plan

  • Visit a form with required fields (Start Workflow, Schedule create, etc.). Confirm a red mono asterisk renders close to the right of each required label, vertically aligned with the label text.
  • Chrome DevTools → Rendering → Emulate vision deficiencies: Achromatopsia. The asterisk shape remains a clear required-indicator signal where the old dot would have looked decorative.
  • Tab into a required field with VoiceOver/NVDA. Confirm "required" is announced (via the native required attribute) and the asterisk is not announced separately.

🤖 Generated with Claude Code

A11y-Audit-Ref: 1.4.1-label-required-indicator

…des (WCAG 1.4.1)

Two SC 1.4.1 Use of Color fixes:

- Label required-field indicator: replace the 6x6 red dot with a
  red asterisk (aria-hidden) so users with color-perception
  differences see a shape signal, not just a color signal. The
  programmatic required state continues to come from native HTML
  `required` on the input (which the 1.3.1 forwarders ensure).
- Timeline graph nodes (workflow-row, history-graph-row-visual):
  add aria-label to the <g role="button"> wrapper so AT users hear
  the workflow id + status (or event type + classification)
  instead of bare "button". Removes the previous dependency on
  reaching the legend tooltip to decode color.

New i18n keys: workflows.row-accessible-name,
events.row-accessible-name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bilal-karim bilal-karim requested a review from a team as a code owner May 22, 2026 13:59
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
holocene Ready Ready Preview, Comment May 22, 2026 3:00pm

Request Review

@bilal-karim bilal-karim marked this pull request as draft May 22, 2026 14:01
Per the PR scope decision, keep this PR focused on the Label
required-indicator fix only. The timeline graph status accessible-
name fix (workflow-row.svelte, history-graph-row-visual.svelte,
and the supporting i18n keys) will ship as its own separate PR
so the two SC 1.4.1 defects can be reviewed independently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bilal-karim bilal-karim changed the title fix(a11y): non-color signals for required state and timeline graph (WCAG 1.4.1) fix(a11y): non-color signal for Label required indicator (WCAG 1.4.1) May 22, 2026
The previous text-interactive-error class was a no-op for text
color (interactive-error is only registered under backgroundColor
in the theme plugin, not textColor), so the asterisk inherited
the default text color and rendered black/off-white instead of
red. text-danger maps to --color-text-danger (red.700 light /
red.400 dark) which is the proper red text token.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The parent <label> already provides text-sm and font-medium, so
the span inherits both. Only text-danger is doing actual work;
the size/weight/leading classes were redundant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- font-mono: mono asterisks are larger and more geometrically
  centered than proportional ones, making them feel like a proper
  visual indicator rather than a tiny text-style superscript.
- leading-none: tightens the span's line-box to the character.
- translate-y-0.5: small downward nudge so the asterisk aligns
  with the label baseline rather than sitting above it.
- -ml-1: reduces the gap to the preceding label text (8px -> 4px).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bilal-karim bilal-karim marked this pull request as ready for review May 22, 2026 15:00
@github-actions github-actions Bot added a11y Accessibility audit PR a11y:no-fix-doc No A11y-Audit-Ref line; audit team triage a11y:bucket-1 Bucket 1: design-mergeable, CSS / tokens a11y:sc-1.4.1 and removed a11y:no-fix-doc No A11y-Audit-Ref line; audit team triage labels May 28, 2026
@bilal-karim bilal-karim merged commit d264b87 into main May 29, 2026
19 checks passed
@bilal-karim bilal-karim deleted the a11y/1.4.1-use-of-color branch May 29, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a11y:bucket-1 Bucket 1: design-mergeable, CSS / tokens a11y:sc-1.4.1 a11y Accessibility audit PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants