Skip to content
easeweb
Search topics

Custom checkboxes that keyboards and screen readers skip

A sign-up form draws its own rounded checkboxes and hides the real ones with display: none, so a mouse can tick them but Tab, Space and screen readers never find them.

WCAG 2.2
SC 2.1.1ASC 4.1.2ASC 1.3.1A
Required by
Section 508 · EN 301 549 (EU)
Broken input[type="checkbox"] { display: none; }
The accessibility problem illustrated: Motor:How do I tick it?
01

The problem

Keyboard, switch and screen reader users can't reach or tick the boxes, so they can't agree to the terms or create an account.

02

Try it

Press Tab to move through the sign-up form, Space to tick each box, then Enter on Create account.

With a mouse, both boxes tick. The panel shows what a screen reader hears as focus moves. Can you agree to the terms without a mouse?

Broken Can you fix this?

BrokenThe checkbox hidden with display: none

Sign up

Screen reader says:

(Tab through the form)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Keep the real input on the page: draw the box on it, put it over the box, or colour it with accent-color.

  1. 1Keep the real checkbox or radio button on the page, in the Tab order and in the accessibility tree.
  2. 2Draw the tick and the focus ring from the input's own checked and focus states.
  3. 3Show checked with a tick or a dot, not by colour alone.
Before The checkbox hidden with display: none
<form action="/sign-up" method="post">  …  <label class="check">    <input type="checkbox" name="offers">    <span class="box"></span>    Email me about offers  </label>  <label class="check">    <input type="checkbox" name="terms" required>    <span class="box"></span>    I agree to the terms  </label>  <button type="submit">Create account</button></form>
After

The box drawn on the input itself

<form action="/sign-up" method="post">  …  <label class="check">    <input type="checkbox" name="offers">    Email me about offers  </label>  <label class="check">    <input type="checkbox" name="terms" required>    I agree to the terms  </label>  <button type="submit">Create account</button></form>

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

A checkbox can look like anything, as long as the real one is still there.

Six ways sites draw checkboxes and radio buttons. Click them, then put the mouse aside and try them with Tab, Space and the arrow keys: four pass, one is skipped by Tab, and one shows the choice only by a tint.

In the design file

  • Name each drawn box, chip, swatch or card a checkbox or a radio button in the design file, so it is built on the real one.
  • Draw every option with its focus ring, as it looks when reached with Tab.
  • Show checked and chosen with a tick, a dot or a ring as well as colour, and check them in greyscale.
  • Write the ratio of the box’s outline against the page beside it, at least 3:1. The example’s grey outline is 4.83:1.
  • Draw the options in Windows high-contrast mode, where fills disappear and the tick, the dot and the outline must still show.

Passes

  • Filter chips that gain a tick Off, an outlined pill with a #6b7280 edge, 4.83:1; on, a violet edge, a pale tint and a tick before the word, in #3730a3, 8.88:1 on the tint. The tick says on without the colour, and the whole chip is the checkbox, so a click, a tap or Space anywhere on it works.
  • Delivery
    Delivery options as cards, the radio showing Each card is one radio button, and a click anywhere on it chooses it. The circle stays in the corner, its 4.83:1 edge filled with a violet dot when chosen, so the choice reads without the tint; the chosen card also takes a violet edge. Tab stops on the group once, and the arrow keys move between the cards.
  • Colour: Sage
    Colour swatches with a ring and a tick Round swatches that are radio buttons, the chosen one ringed in #111827, 17.74:1 on white, with a tick inside and its name written after “Colour”. People who can’t tell sage from navy read the name; the arrow keys move between the colours.
  • A round to-do check that draws its tick Ticked, the circle fills violet and a white tick draws itself in 0.3 seconds, then stops, and the task is struck through in #6b7280. The tick and the line say done in greyscale; with reduced motion, the tick simply appears.

Fails

  • Size
    Size tiles with the radios hiddenWCAG 2.1.1 S, M, L and XL as outlined tiles, the chosen one filled #111827. A click picks a size, but the radios behind them are hidden, so Tab goes straight past all four and a screen reader hears only the letters. Try it with Tab.
  • Plan
    Plan cards chosen by a tint aloneWCAG 1.4.1 The radio buttons are real, so the keyboard works, but nothing is drawn for them: the chosen plan is shown only by a #eef2ff tint, 1.12:1 against the white card beside it. In greyscale, in high-contrast mode or on a washed-out screen, both cards look the same.
05

Verify the fix

5 checks.

Test with: Keyboard, Screen reader, Mouse, Forced colors, Touch

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 form components or the theme change.

Limits

This is a starting pattern, not a guarantee for every application. The CSS is a sketch: check the size of the box, the contrast of its border and the focus ring against your own palette. A rebuilt checkbox with ARIA and a wrong state is a different failure, covered in invalid ARIA that misleads screen readers; a group of options with no question tied to it is covered in radio buttons and checkboxes without a group name; and a checkbox drawn as a switch in toggle switches that don't say whether they are on. Test the whole form with a keyboard, a screen reader and a contrast theme.

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