Chat thread — Accessibility
Roles
ChatThreadrendersrole="log"witharia-labelset by the host (the other party's name). A log announces new children as they arrive. An e-mail conversation view that does not useChatThreadshould give its own containerrole="list"withrole="listitem"rows.ChatBubblerenders plaindivs (no role override, noaria-labelon the bubble: it would replace the real multi-line DOM text and break "Find on page" and browser translation).
Reading order inside a message row
- A visually-hidden (
.acrm-sr) sender label (fromLabel) — "Já" / the contact's name — BEFORE the bubble, so a reader reaching a single message knows whose it is. A visiblesenderNamein the meta row isaria-hiddento avoid reading the name twice. - The message text, as real DOM content.
- Attachments (host-rendered
Attachment/.cht-att; links and buttons keep their own roles). - The meta row: time, then — for outgoing messages with a
state— the status icon (decorative) followed by a visually-hiddenstateLabel("přečteno"/"read"), then host actions.
Keyboard
ChatBubble has no interactive elements of its own. Host actions are real <button>s (.cht-link) in the meta row: reachable by Tab in reading order, visible :focus-visible (colour change + underline), toggles expose aria-expanded (e.g. "Original"). A clamped long message offers "Show all" / "Show less" (.cht-more, inside the bubble, aria-expanded) as such a button; clamped text stays fully available to assistive technology (the clamp is visual) once expanded.
Touch
Host actions in the meta row are text buttons. Where the host needs the 44 px target (--tap-min) on touch it extends the hit area with an invisible pseudo-element, without changing the look.
Icons
check / checks / clock / alert-circle come from the DS icon set. They convey state, so WCAG 1.4.11 (non-text contrast, 3:1) applies. read uses --accent on the page (4.29:1 light, 4.04:1 dark).
Contrast (WCAG 2.1, measured (L1+0.05)/(L2+0.05))
| element | light | dark | target | status |
|---|---|---|---|---|
incoming text — --fg on --line-100 | 16.0:1 | 13.1:1 | AA 4.5:1 | met in both |
outgoing text — --fg-on-accent on --accent | 4.44:1 | 4.44:1 | AA 4.5:1 | 0.06 short (same pair as Button primary) |
meta (time, host actions) — --fg-muted on page | 2.75:1 | 3.82:1 | AA 4.5:1 | documented limitation (owner decision R21) |
read icon — --accent on page | 4.29:1 | 4.04:1 | non-text 3:1 | met in both |
The meta tone is the owner-approved quiet metadata colour (--fg-muted); the outgoing text pair is the accent / on-accent pair used app-wide. Both are flagged for a token-level decision, not fixed per component.
Source: docs/discussion/chat-thread.a11y.md · GitLab