fix(a11y): increase annotation toggle touch target to 44×44px minimum #354
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The annotation toggle button in
PdfControls.svelteusespx-2 py-1which computes to approximately 28×24px — below the 44×44px minimum required by WCAG 2.2 and the project's own standard for its 60+ transcriber audience.This was surfaced as a pre-existing issue during the PR #349 review by Leonie Voss (UI/UX).
Affected file
frontend/src/lib/components/PdfControls.svelte— the annotation toggle button (lines 89–123 in the PR #349 state).Acceptance Criteria
min-h-[44px]or equivalentProposed fix
Changing
px-2 py-1→px-3 py-2 min-h-[44px]increases the tap area to comply with the project standard.Background
👩🎨 Leonie Voss — UI/UX Design Lead & Accessibility Strategist
Observations
px-2 py-1with atext-xslabel and ah-3.5 w-3.5icon renders at approximately 28×24 px — well below the WCAG 2.2 §2.5.8 minimum of 44×44 px. This is a Critical accessibility failure for the 60+ transcriber audience using laptops and tablets.px-3 py-2 min-h-[44px]) is correct and matches the pattern already used inBackButton.svelte,ConfirmDialog.svelte, andPagination.svelte.rounded p-1with ah-4 w-4(16 px) icon, producing a ~24×24 px tap area. These are also below the 44 px floor and need the same treatment — this issue scopes them out, but they are the same violation in the same file.aria-pressed. Screen readers will announce it as a generic button with no indication that it represents an on/off state. Thearia-labeltext compensates partly, butaria-pressedis the correct semantic.aria-labelvalues (Zurück,Weiter,Verkleinern,Vergrößern) are hardcoded German strings — not wired through Paraglide. This is a pre-existing issue, not introduced here, but worth flagging while the file is open.Recommendations
px-3 py-2 min-h-[44px]on the annotation toggle. Also addmin-w-[44px]to guard against the button becoming too narrow when the label is very short in any locale.aria-pressed={showAnnotations}to the annotation toggle button. This communicates toggled state to screen readers without relying on the label text changing.min-h-[44px] min-w-[44px] p-2— the visual change is imperceptible (icon is centered) but the tap area doubles. Open a separate micro-issue if you want to keep this PR atomic.aria-labelstrings with Paraglide message calls — but file that as a separate cleanup issue rather than expanding this one.Open Decisions
👨💻 Felix Brandt — Fullstack Developer
Observations
px-2 py-1→px-3 py-2 min-h-[44px]. The diff is trivial and the proposed class string in the issue body is ready to paste.PdfControls.svelte.spec.ts) covers annotation visibility, label text, and contrast class — but has no test asserting themin-h-[44px]class. The acceptance criterion says "a unit test asserts the button carriesmin-h-[44px]," so the test needs to be added. The pattern fromPersonMentionEditor.svelte.spec.tsapplies directly:vitest-browser-svelte+render— this fits the existing pattern in the file perfectly.p-1, ~24 px) violate the same rule. They are out of scope for this issue, but should be tracked separately.$props()destructuring and type annotation are correct Svelte 5 style. No rune issues.Recommendations
describeblock structure, or add a newdescribe('PdfControls — touch targets', ...)block to group the WCAG-related assertions.waitFororexpect.elementfor a className check — a synchronous DOM query afterrenderis sufficient and faster (matches the project's established pattern for class assertions in this file).🏗️ Markus Keller — Application Architect
Observations
PdfControls.svelte). No architectural boundaries are crossed, no new routes or packages are introduced, and no backend changes are required. There is nothing architecturally significant to flag.frontend/src/lib/document/viewer/— the right domain package for a PDF viewer control component.Recommendations
🔒 Nora "NullX" Steiner — Application Security Engineer
Observations
showAnnotationsprop) — it does not perform API calls, modify data, or expose privileged information.aria-labeldriven bym.pdf_annotations_hide()/m.pdf_annotations_show()(Paraglide) is safe — these are compile-time string lookups, not user-controlled input.Recommendations
🧪 Sara Holt — QA Engineer & Test Strategist
Observations
PdfControls.svelte.spec.tscovers three describe blocks: visibility, label text, and contrast class. The touch target is not currently tested — the third acceptance criterion (A unit test asserts the button carries min-h-[44px]) is unmet.PersonMentionEditor.svelte.spec.ts(checkingclassName.toContain('min-h-[44px]')) is the correct model. The test forPdfControlsshould follow the same shape.container.querySelectorAll('button')+getAttribute('aria-label')to locate the annotation button — this works and is already used in the contrast test in the same file. Consistency is good.px-2 py-1class proves it is meaningful.expect.element— synchronous afterrenderis fine, as proven by the contrast test at line 53–66 of the existing spec.Recommendations
min-h-[44px]absent frompx-2 py-1). Apply the fix. Confirm green.🚀 Tobias Wendt — DevOps & Platform Engineer
Observations
npm run testinvocation in CI picks up new spec content automatically — no pipeline changes needed.Recommendations
📋 Elicit — Requirements Engineer
Observations
min-h-[44px]") — the criterion is clear and implementation-ready.aria-pressedsemantic for the toggle state is not mentioned. The button communicates its state through changing label text, which is WCAG-compliant, butaria-pressedwould be the more semantically precise solution per ARIA Authoring Practices. This is a "should" improvement, not a blocker.aria-labelstrings on nav buttons ("Zurück","Weiter","Verkleinern","Vergrößern") are not i18n-compliant. Same file, pre-existing, not in scope — but should be tracked.Recommendations
aria-pressedto the acceptance criteria as a "should" (not "must") to improve semantic correctness without blocking the fix.fix(a11y): increase touch targets on PdfControls nav and zoom buttonsto close the gap on the remaining four buttons in the same component.aria-labelstrings so they are tracked rather than forgotten.Open Decisions
aria-pressedscope: include in this issue as an additional AC, or file separately? Given the file is being touched anyway and the change is two tokens (aria-pressed={showAnnotations}), folding it in costs almost nothing and closes a real semantics gap.🗳️ Decision Queue
Two open decisions were raised across the review. Both are genuine tradeoffs needing human judgment.
1. Scope: fix only the annotation toggle, or also the four icon-only buttons?
Raised by: Leonie (UX), Sara (QA), Tobias (DevOps)
The four nav/zoom buttons (
p-1, ~24 px) have the same WCAG 2.2 §2.5.8 violation as the annotation toggle. Fixing them in this PR costs three lines of Tailwind changes and no additional test overhead (class-level assertions). Deferring means a second PR touching the same file.Options:
2.
aria-pressed: fold into this issue or file separately?Raised by: Leonie (UX), Elicit (RE)
The annotation toggle lacks
aria-pressed={showAnnotations}. Adding it is two tokens in the template and closes a genuine ARIA semantics gap (the button conveys its state through label text changes today, which is functional but not the ARIA Authoring Practices recommendation for toggle buttons). No new test is needed — the existing label-based assertions remain valid.Options:
aria-pressed={showAnnotations}to this PR. AC-1 and AC-2 are unaffected; AC-3 could optionally assertaria-pressedtoo. Low risk, minimal diff.These items do not block the core fix. The class change and its test can be implemented under any combination of these decisions.
Implemented in PR #493 (
fix/issue-354-annotation-touch-target), commitd4abe994.Changes:
min-h-[44px] min-w-[44px](WCAG 2.2 §2.5.8)p-1→p-2 min-h-[44px] min-w-[44px]px-2 py-1→px-3 py-2 min-h-[44px] min-w-[44px]aria-pressed={showAnnotations}added to annotation toggle (ARIA 1.2 toggle semantics)Tests added: 5 new assertions in the WCAG 2.2 §2.5.8 suite — min-h/min-w for each button type + aria-pressed state.