Skip to content
easeweb
Search topics

Multi-selects with silent ticks and mouse-only chips

A Skills field shows the chosen skills as chips whose × is an svg with a click handler, and ticks its list with a class, so a keyboard can't remove a chip and a screen reader never hears which skills are chosen.

WCAG 2.2
SC 2.1.1ASC 4.1.2A
Required by
Section 508 · EN 301 549 (EU)
Broken <svg class="chip-remove" viewBox="0 0 16 16">
The accessibility problem illustrated: Motor:How do I remove Research?
01

The problem

Keyboard users can't remove a chosen skill, and screen reader users can't tell which skills are chosen, so neither can check or correct the field.

02

Try it

Without the mouse: Tab to Skills, press Enter to open it, choose Writing with the arrow keys and Space, press Escape, then remove Design.

Skills is a dropdown that holds the chosen skills as chips. In Broken 1, Tab never stops on an ×, and a chosen skill leaves the list, so nothing you choose can be taken back. Clicking an × works. In Broken 2, untick in the list instead, and watch the panel: does it ever say which skills are ticked? On the fixed side, the checkbox fix moves between boxes with Tab.

Broken Can you fix this?

Skills
Design Research

Screen reader says:

(Tab to Skills)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Give every chip a remove button Tab reaches, and let every option say in code whether it is chosen.

  1. 1Every chip's × is a button Tab reaches, named after its chip.
  2. 2Every option says in code whether it is chosen: a checkbox, a select or aria-selected.
  3. 3Removing a chip moves focus to the next chip or back to the field.
Before

Chosen skills that only a mouse can remove

<span id="skills-label">Skills</span><div class="skills-field">  <span class="chips">    <span class="chip">      Design      <svg class="chip-remove" data-for="skill-design" viewBox="0 0 16 16">…</svg>    </span>    <span class="chip">      Research      <svg class="chip-remove" data-for="skill-research" viewBox="0 0 16 16">…</svg>    </span>  </span>  <button type="button" class="skills-toggle" aria-labelledby="skills-label"    aria-haspopup="listbox" aria-expanded="false" aria-controls="skills-list">    <span class="placeholder">Add a skill</span>    <svg class="chevron" viewBox="0 0 16 16" aria-hidden="true">…</svg>  </button></div><ul id="skills-list" class="skills" role="listbox" tabindex="-1" aria-labelledby="skills-label" hidden>  <li id="skill-design" role="option" hidden>Design</li>  <li id="skill-writing" role="option">Writing</li>  <li id="skill-research" role="option" hidden>Research</li>  <li id="skill-coding" role="option">Coding</li>  <li id="skill-video" role="option">Video editing</li></ul>
After

Checkboxes in the dropdown, with a button on each chip

<span id="skills-label">Skills</span><div class="skills-field">  <span class="chips">    <span class="chip">      Design      <button type="button" class="chip-remove" data-for="skill-design" aria-label="Remove Design">        <svg viewBox="0 0 16 16" aria-hidden="true">…</svg>      </button>    </span>    <span class="chip">      Research      <button type="button" class="chip-remove" data-for="skill-research" aria-label="Remove Research">        <svg viewBox="0 0 16 16" aria-hidden="true">…</svg>      </button>    </span>  </span>  <button type="button" class="skills-toggle" aria-labelledby="skills-label"    aria-expanded="false" aria-controls="skills-list">    <span class="placeholder">Add a skill</span>    <svg class="chevron" viewBox="0 0 16 16" aria-hidden="true">…</svg>  </button></div><div id="skills-list" class="skills" role="group" aria-labelledby="skills-label" hidden>  <label class="skill">    Design    <input type="checkbox" id="skill-design" name="skills" value="design" checked>  </label>  <label class="skill">    Writing    <input type="checkbox" id="skill-writing" name="skills" value="writing">  </label>  <label class="skill">    Research    <input type="checkbox" id="skill-research" name="skills" value="research" checked>  </label>  <label class="skill">    Coding    <input type="checkbox" id="skill-coding" name="skills" value="coding">  </label>  <label class="skill">    Video editing    <input type="checkbox" id="skill-video" name="skills" value="video">  </label></div>

Why this fix: Use native HTML first

Fixing this with an AI coding assistant? Get this guide as Markdown, or get every guide in your coding agent.

04

Design ideas

Chosen values can look like anything, as long as the code says what is chosen.

Five more ways sites draw several choices. Click them, then put the mouse aside and try them with Tab, Space and Enter: three pass, one has an × that Tab never reaches, and one fills its pills without saying so in code.

In the design file

  • Name the options in the design file as checkboxes, and each chip’s × as a button, so both are built on the real elements.
  • Write each × button’s name beside it, with its chip’s word, such as “Remove Design”.
  • Draw every × and every option with its focus ring, as it looks when reached with Tab.
  • Mark where focus goes after a chip is removed, the next chip or, when none is left, the field.
  • Keep each × visible at rest, not only on hover, since keyboard users never hover, and touch users see it only after a tap, if at all.

Passes

  • Skill chips that gain a tick Every skill is a pill, and the pill is a checkbox. Off, a #6b7280 edge, 4.83:1; on, a teal edge, the #ccfbf1 tint and a tick before the word in #115e59, 6.73:1 on the tint. No separate chips to remove: Space unticks a pill where it stands.
  • Skills
    2 chosen
    A tick list with a count and Clear all No chips: a line above the checkboxes says how many are chosen, beside a Clear all button. The count sits inside the group, where a screen reader finds it with the list, and every skill is unticked where it is listed, so there is nothing extra to reach.
  • DesignWriting
    Chips cut short by a “+2 more” button Two chips show, then a “+2 more” button that opens the rest and says it is open. Every chip, shown or opened, has its own × button, so none is out of reach.

Fails

  • Design Writing Research Coding
    Clean chips whose × shows on hoverWCAG 2.1.1 At rest the chips are plain words; pointing at one shows its ×. The × is not a button, so Tab never reaches it, and on a touch screen it shows only after a tap, if at all. Try it with Tab.
  • Pills that fill when chosen, and say nothingWCAG 4.1.2 Each pill is a button, so Tab and Enter work, and a chosen one fills #0f766e with white words, 5.47:1. But the fill comes from a class: a screen reader hears “Writing, button” whether it is chosen or not.
05

Verify the fix

5 checks, no mouse.

Test with: Keyboard, Screen reader, Forced colors

0 of 5 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared multi-select component changes.

Limits

This is a starting pattern for a short list of fixed options. It doesn't cover grouped options, options loaded as the person scrolls, or reordering the chips. Test the complete journey, with your real options, in the browsers and assistive technology you support.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

Keep this fixed as your code changes.

Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.

How retests work