How to make a feedback widget accessible
Use real buttons for every control, label every field, return focus to the trigger when the panel closes, and check the contrast of the button color. Test with the Tab and Escape keys first, then with a screen reader, because automated checks miss focus order.
By Rafael Thayto · Last updated
Use real buttons for every control
A control that looks like a button should be a button. Keyboard users move between controls with Tab and press them with Enter or Space. A div with a click handler gets none of that for free, and a screen reader may not announce it at all.
The Escuta Produto widget builds every control as a real button element: the floating button, the close button, each feedback type, each star and the send button. A keyboard user can reach all of them in order. The same check applies to any widget you build or install, so Tab through it before you trust it.
Dialog semantics and what they promise
The panel has role="dialog", a name taken from its title ("Send us feedback" or "Envie seu feedback"), and aria-modal="false". The false value matters. It tells assistive technology that the rest of the page is still active. The widget does not trap focus, so Tab can move out of the panel into the page behind it. The page is not made inert.
For a short form that is a reasonable choice, because a visitor who wants to leave the panel can. Do not describe the widget as a modal dialog in your own documentation, and do not add a focus trap on top without testing how it interacts with the page's own menus.
Escape, focus and returning to the trigger
Pressing Escape anywhere on the page closes an open panel. When the panel opens, the widget remembers which element had focus. When the panel closes, focus returns to that element, and if nothing was focused and the floating button is showing, focus goes to the floating button. The message box receives focus about 30 milliseconds after opening, so a keyboard user can start typing at once.
Run this test: Tab to a button that has data-escuta-open, press Enter, type a sentence, press Escape, and confirm that focus lands back on the same button. If focus lands on the top of the page, a screen reader user loses their place, so fix it before release.
Labels, names and visible prompts
Every form field needs a name a screen reader can announce. The email field has a real label tied to its input, so it reads as "Email (optional, so we can reply)". The message box has no visible label. Its accessible name comes from the placeholder for the selected type, such as "What went wrong? What did you expect to happen?".
That placeholder is the only prompt the message box shows, and it disappears as soon as someone types. For your own forms, prefer a visible label above the field and keep the placeholder as an example. A visible label also helps people with low vision or with memory difficulties, who may forget what a box is for.
The rating question is the label of the star group: the stars sit in a role="group" element named by the visible question, so a screen reader announces the question before the five buttons named "1/5" to "5/5". Each star is a toggle button with aria-pressed, and only the selected star reports itself as pressed, so the announcement says which rating is chosen. Pressing the selected star again clears the rating.
Color contrast on the button
The widget uses your accent color for the floating button and the send button, with white text on both. The contrast depends on the color you choose, and the widget does not check it. Aim for at least 4.5 to 1 for normal text, which is the WCAG AA level for body text. A bright yellow or light pastel usually fails with white text, while a deep blue or deep green usually passes.
Check the footer as well. The brand line at the bottom of the panel uses a mid gray on white that meets the 4.5 to 1 level. It is part of the widget, so you cannot change its color with an attribute.
What the Escuta Produto widget handles, and what is left to you
The widget covers the basics so you can focus on your own page:
- Every control is a real button, and the type buttons expose
aria-pressed. - The star rating is a labelled group, and the selected star reports itself as pressed.
- The message field has an accessible name that follows the selected type.
- Escape closes the panel and focus returns to the element that opened it.
- With the reduced-motion setting on, the panel opens without the slide animation and the floating button no longer lifts on hover.
- The footer text meets the 4.5 to 1 contrast level.
Two things stay with you. First, the contrast of your accent color, because the widget uses whatever data-color you pass. Second, the panel is non-modal and has no focus trap. That suits a short form that people may want to leave halfway, but if your page needs a modal pattern, open the widget from your own button and test the flow with a screen reader.
Check the Escuta Produto widget with a keyboard and a screen reader
Run these steps on your own install, not on a demo page:
- Load the page and press Tab until the floating button has focus. Confirm the focus outline is visible.
- Press Enter, then Tab through the type buttons, the message, the stars, the email field and the send button in order.
- Press Escape and confirm focus returns to the button you started from.
- Turn on a screen reader, such as VoiceOver or NVDA, and listen to the dialog name, the type buttons and the error message when you send an empty form.
- Check the color contrast of the button with a contrast checker.
For setup details, see the widget docs. For the wording of the trigger that sits in front of the panel, read what a feedback button should say. If your page is on a phone, designing a feedback widget for mobile screens covers touch targets and the keyboard overlap, which affects the same users.
Set up an accessible trigger in Escuta Produto
Keep the floating button for most sites, since it is the most predictable control. On pages where a bug report has a clear place, such as a settings screen, use data-trigger="none" and add a real button with data-escuta-open="bug". Give the button text that describes the action, check its contrast, and repeat the keyboard test on that page before you ship.
Frequently asked questions
What makes a feedback widget accessible?
Real buttons for every control, labelled fields, a dialog name, focus that returns to the trigger after closing, and enough contrast on the button color. Test with the keyboard first, then with a screen reader.
Should a feedback form trap keyboard focus?
Not for a short feedback form. A non-modal panel lets visitors leave with Tab, which is acceptable here. A focus trap helps only when the panel blocks the page, and it adds risk if you get it wrong.
How do I check the contrast of my feedback button?
Use a contrast checker with your accent color and white text. Aim for at least 4.5 to 1 for normal text. The Escuta Produto widget does not check contrast, so you need to check the color you pick.
Related
- Feedback widget best practicesWhere to place a feedback button, how to keep it fast and accessible, and how to protect it from spam. Practical rules for in-app feedback widgets.
- What should a feedback button say?How to word a feedback button: verbs or nouns, labels that match each page and feedback type, localized copy, and how to replace the default Feedback button.
- Designing a feedback widget for mobile screensDesigning a feedback widget for phones: thumb reach, keyboard overlap, bottom navigation conflicts and the checks to run on a real device before you ship.
- Why embeddable widgets use Shadow DOMWhat Shadow DOM isolates in an embeddable feedback widget, what it leaves open to the host page, how to theme across the boundary, and how to test it.