Skip to content
easeweb
Search topics

Select-all checkboxes whose dash is never read out

A select-all checkbox shows a dash when only some rows are ticked, but the dash comes from a class, so screen readers still announce it as not checked.

WCAG 2.2
SC 4.1.2A
Required by
Section 508 · EN 301 549 (EU)
Broken all.classList.toggle('partial', ticked > 0 && !all.checked);
The accessibility problem illustrated: No vision:Are any invoices ticked?
01

The problem

Screen reader users hear the select-all as not checked while some rows are ticked, so they can't tell from it that anything is selected.

02

Try it

Tick two invoices, then go back to Select all and listen to how it is read.

Tab to March and press Space, then Tab to April and press Space, and press Shift + Tab twice. The panel shows what a screen reader says as focus moves: compare what it says on Select all with the box you see, then press Space there.

Broken Can you fix this?

BrokenThe dash drawn from a class

Invoices

Screen reader says:

(Tab through the list)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Give the select-all a mixed state in code, and draw the dash from it.

  1. 1Set a mixed state whenever some rows but not all are ticked: the indeterminate property, or aria-checked="mixed".
  2. 2Draw the dash from that state, never from a class, and as a mark, not by colour alone.
  3. 3Never put aria-checked on a native checkbox.
Before The dash drawn from a class
<form action="/invoices/download" method="post">  <label class="check">    <input type="checkbox" id="select-all">    Select all  </label>  <ul class="invoices">    <li>      <label class="check">        <input type="checkbox" name="invoice" value="2026-03">        March 2026      </label>    </li>    …  </ul>  <button type="submit">Download selected</button></form>
After

The indeterminate property

<form action="/invoices/download" method="post">  <label class="check">    <input type="checkbox" id="select-all">    Select all  </label>  <ul class="invoices">    <li>      <label class="check">        <input type="checkbox" name="invoice" value="2026-03">        March 2026      </label>    </li>    …  </ul>  <button type="submit">Download selected</button></form>

Why this fix: Use native HTML first

04

Design ideas

None, some, all: three states, and a mark for each.

Four ways sites draw a select-all over a list. Tick and untick the rows with the mouse, or with Tab and Space: three show “some” with a mark or words of their own, and one only with a paler fill.

In the design file

  • Draw the select-all empty, with a tick when every row is chosen, and with its own mark when only some are.
  • Make the “some” mark a shape, such as a dash or a small square, never only a paler fill, and check the three states in greyscale.
  • Write the ratio of each mark against what it sits on, at least 3:1. The example’s violet dash on white is 6.29:1.
  • Note on the select-all that its middle state is the checkbox’s own, set in code, not a style of its own.
  • Draw the three states in a Windows contrast theme, where fills disappear and every mark must still show.

Passes

  • A small square inside the box Some chosen, the box keeps its white fill and #6b7280 edge, 4.83:1, and holds a small violet square, 6.29:1 on the white; all chosen, it fills violet with a tick. Three shapes, so the states read in greyscale, and the square is drawn as a border, which a contrast theme keeps.
  • A dash in an outlined box A lighter look than a filled box: some chosen, the edge turns violet and a violet dash sits on the white, 6.29:1; only all chosen fills the box. The dash, not the colour, tells some from none, and it is drawn as a border, so it stays in a contrast theme.
  • 2 of 3 selected
    A selection bar that counts Once a row is chosen, the row above the list becomes a #eef2ff bar: the box with its dash, “2 of 3 selected” in #3730a3, 8.88:1 on the tint, and a Clear button. The count says how many in words, and Clear undoes the choice in one press.

Fails

  • “Some” shown by a paler fillWCAG 1.4.1 All chosen is a violet box with a tick; some chosen is the same box in a pale #c7d2fe with no mark, 1.49:1 against the white of an empty one. The checkbox does report “mixed”, but on screen, in greyscale or in a contrast theme, where the fill disappears, some and none look the same.
05

Verify the fix

4 checks, no mouse.

Test with: Screen reader, Keyboard, Forced colors

0 of 4 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the list component or its checkboxes change.

Limits

This is a starting pattern, not a guarantee for every list. It covers the select-all's state; a checkbox that the keyboard can't reach at all is covered in custom checkboxes that keyboards and screen readers skip, and a list whose chosen options are never read out in multi-selects with silent ticks and mouse-only chips. A tree of checkboxes, where each group has its own select-all, needs the same mixed state at every level. Test the whole list with the screen readers your users rely on.

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.

EaseWeb service

Fixed it? Keep it from coming back.

I turn guides like this one into rules your coding agents follow and checks your CI runs. Then I retest by hand with a keyboard and screen readers, periodically.

See the service