Agent Wranglers

AXS-76Recommended

Make chat screens work with a keyboard and a screen reader

In every chat, with a person or an AI assistant, label the message box and keep focus in it after sending. Put the conversation in one role="log" region, and give each message its author in text.

How to do it

Chat screens break in the same few ways. The input has only a placeholder, focus jumps to the top after sending, and a screen reader reads every new token or nothing at all. Label the input, send on Enter and add a line on Shift+Enter. Start each message with a visually hidden author, such as "Assistant said", so people know who is speaking when they move through the log. Mark the log aria-live="off" while an answer streams. Announce the finished answer once through a status region, as Make streamed answers work with a screen reader says. Give long answers headings and lists in HTML, not in Markdown symbols read aloud. A chat widget you buy must meet the same bar, as Ask for a conformance report before you buy says.

Examples

HTML example

<section aria-labelledby="chat-title">
  <h2 id="chat-title">Ask about your order</h2>
  <div role="log" aria-live="off" id="chat-log">
    <p><span class="visually-hidden">You said:</span> Where is my parcel?</p>
  </div>
  <p role="status" id="chat-status"></p>
  <label for="chat-input">Message</label>
  <textarea id="chat-input"></textarea>
</section>

JavaScript example

await page.getByLabel('Message').fill('Where is my parcel?');
await page.keyboard.press('Enter');
await expect(page.getByLabel('Message')).toBeFocused();
await expect(page.locator('#chat-status')).toHaveText(/\S/);

Python example

page.get_by_label("Message").fill("Where is my parcel?")
page.keyboard.press("Enter")
expect(page.get_by_label("Message")).to_be_focused()
expect(page.locator("#chat-status")).to_have_text(re.compile(r"\S"))

How to check

A browser test focuses the labelled message box, types a question and presses Enter. Focus stays in the box, and the log gets one new message whose text starts with its author. The status region changes once, after the answer ends.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/accessibility/forms-changes-and-time/accessible-chat">Agent Wranglers accessibility playbook</a>. In code you write, add a comment next to it with the same link.