Skip to content
Bugwise
Menu
UI Components

Checkbox

The little box you tick to agree, pick several items or select a whole list at once. Learn its states (including "mixed"), when it beats a switch or a radio button, and the consent and keyboard bugs testers find in it.

30 min Inputs & selection iOS · Android · Web Also called: Check box, Tick box

“I agree to the Terms.” “Remember me.” “Leave at the door.” “Select all.” You tick boxes like these dozens of times a week, usually without thinking. That’s exactly why checkbox bugs are so sneaky: the box you can’t tap, the “Select all” that lies about how many emails you’re deleting, the marketing consent that was ticked for you.

A checkbox is also where UI testing meets legal testing. Let’s learn both sides.

What is a checkbox?

A checkbox is a small square the user ticks to say “yes, include this”. Each checkbox is independent: ticking one doesn’t untick the others. And, unlike a toggle switchToggle switchAn on/off control that applies a setting immediately, like Wi-Fi or Dark mode.Open in glossary →, ticking a checkbox usually does nothing on its own. The choice is applied when the user presses a button like Continue, Save or Pay.

You’ll see checkboxes used for:

  • A single yes/no in a form: I agree to the Terms, Remember me, Billing address is the same as delivery.
  • Picking several items from a list: cuisines in a food app filter, newsletter topics, pizza toppings.
  • Bulk actions: ticking emails, photos or files, then pressing Archive or Delete.
  • Consent: Send me offers by email, Share my data with partners.

Anatomy

  1. 1

    Group label (optional)

    Says what the set of checkboxes is about. On the web it is a <legend> inside a <fieldset>.

  2. 2

    Box (container)

    Empty when unchecked, filled when checked. A dash means "mixed": some, but not all, items below are checked.

  3. 3

    Checkmark

    Shows the checked state with a shape, not only a color.

  4. 4

    Label

    Says what you agree to or pick. Tapping it must toggle the box too.

  5. 5

    Touch target

    The tappable area. The box is only about 18 px, but the target must be at least 44×44 pt (iOS) or 48×48 dp (Android).

  6. 6

    Helper or error text

    Extra info, or the error when a required box was left unchecked ("You need to accept the Terms").

The states

A checkbox has more states than “ticked or not”. Each one needs testing:

StateLooks likeMeaning
UncheckedEmpty boxNot selected
CheckedFilled box with a tickSelected
Mixed (indeterminate)Filled box with a dashParent of a list where some children are checked
DisabledFaded, keeps its tick or notCan’t be changed right now
ErrorRed box + error textA required box was left unchecked
FocusedRing or highlight around itKeyboard focus is here (web, external keyboards)

Checkbox vs toggle switch vs radio button

The fastest way to spot a wrong component is to ask two questions: can the user pick more than one? and does it apply immediately?

ComponentHow many?When it appliesExample
CheckboxZero, one or manyOn Submit / SaveToppings, “I agree to the Terms”
Toggle switchOne setting, on/offImmediatelyDark theme, Wi-Fi
Radio buttonsExactly one of a fewUsually on SubmitStandard / Express delivery
Segmented controlExactly one of 2–5ImmediatelyDay / Week / Month

See also the radio button, toggle switch and segmented control pages.

Designs & variants

The idea is the same everywhere, but the platforms disagree on what it looks like. iOS doesn’t even have one.

Every checkbox here works. Click the label text too, and try Tab + Space.

Material 3 checkbox

Android

An 18 dp box with rounded corners inside a 48 dp touch target. A round highlight (state layer) appears on hover, press and focus.

Native web checkbox

Web

A plain <input type="checkbox"> with a <label>. It looks slightly different in every browser, but keyboard, label clicks and screen readers work for free.

Custom web checkbox

Web

Styled to match the brand. Built on a hidden real input, so it still works with the keyboard. Many custom checkboxes are just a <div>, and that's where the bugs live.

Cuisines

iOS: checkmarks in a list

iOS

iOS has no checkbox control. Multi-select lists show a blue checkmark on the right of each selected row, and the whole row is tappable.

  • Unchecked
  • Checked
  • Mixed
  • Focused
  • Disabled
  • Disabled on
  • Error
  • Error on

All the states

Test each one, in light and dark mode. Disabled boxes keep showing their value. "Mixed" (indeterminate) only appears on a parent checkbox whose children are partly checked.

“Select all” and the mixed state

A parent checkbox that controls a list is one of the most bug-prone patterns in any app. The rule is simple, and it must hold after every click:

What the parent should show

No child checkedUnchecked
Some children checkedMixed (dash)
All children checkedChecked

2/5 selected · aria-checked="mixed"

Try: uncheck one email, check them all one by one, click the parent while it shows a dash, archive everything. The count, the parent and the Archive button must always agree.

What happens when you click a parent that shows a dash? Most apps select all, some clear all. Both are fine if the behavior is consistent and matches the spec. What’s never fine: the parent saying “all” when it isn’t, or a count that disagrees with the ticks.

When to use it

A checkbox is the right choice when:

  • The user can pick any number of options, including none: Wi-Fi, Parking, Pool.
  • There’s one optional yes/no in a form: Remember me, Send me a copy.
  • The user must actively agree to something before continuing: I accept the Terms.
  • The choice is applied later, when the user presses a button.

Good and bad uses

Checkboxes in a form with Save

Email me about

Booking confirmations
Price drop alerts
Save preferences

Nothing changes until Save preferences. That’s what checkboxes communicate.

Switches in a form with Save

Email me about

Booking confirmations
Price drop alerts
Save preferences

Switches promise an instant effect. Here users can’t tell if the change already happened or needs Save.

The whole row is the hit area

I agree to the Terms of Service

Tap target: the whole row (box + label).

Tapping the label ticks the box. Easy on a phone, and required for accessibility.

Only the tiny box reacts

I agree to the Terms of Service

Tap target: a 14 px box. The text does nothing.

A 14 px target on a touch screen. Users tap the text, nothing happens, and they think the form is broken.

Marketing consent left unticked

I agree to the Terms and Privacy Policy *
Send me deals and partner offers by email
Create account

The user has to opt in actively. Terms and marketing are separate boxes.

Marketing consent pre-ticked

I agree to the Terms and Privacy Policy *
Send me deals and partner offers by email
Create account

The user “agreed” to offers without doing anything. In many countries this doesn’t count as consent.

Long label with a hanging indent

I confirm that I am over 18 and that the passenger names match the passports exactly

The box lines up with the first line and the text wraps under itself.

Text wraps under the box

I confirm that I am over 18 and that the passenger names match the passports exactly

Hard to scan, and with large text it’s unclear which box belongs to which sentence.

Also avoid checkboxes when the user must pick exactly one option (use radio buttons) and for a single setting that applies immediately (use a switch).

Common bugs

#BugWhat you seeTypical severity
1Label not clickableTapping the text does nothing, only the tiny box reactsMedium
2“Select all” out of syncParent stays ticked after you untick one item, never shows mixed, or the count is wrongHigh (if it drives a bulk delete)
3Pre-ticked consentMarketing or data-sharing boxes are ticked by defaultHigh (legal risk)
4Not keyboard operableA custom checkbox can be focused but Space doesn’t toggle it, or it can’t be focused at allHigh (for affected users)
5Required box not enforcedThe form submits without “I agree”, or only the browser checks it and the server accepts the request anywayHigh
6Error not explainedA required box turns red with no text, or the error isn’t announced to screen readersMedium
7State lostTicks disappear after going Back, rotating, or a validation error elsewhere on the formMedium
8Disabled but clickableA greyed-out box can still be toggled by tapping or with the keyboardMedium
9Long labels breakText wraps under the box, gets truncated, or overlaps at large font sizesLow–Medium
10Silent screen readerVoiceOver / TalkBack doesn’t say “checkbox”, “checked” or the labelHigh (for affected users)

Find the bug

This travel site’s sign-up flow has six checkbox bugs. Explore it like a tester:

  • Click the text next to each box, not just the box.
  • Try to continue without ticking anything. Read the screen carefully.
  • On step 2, use Select all, then untick one topic. Watch the count.
  • Use only the keyboard: Tab to each checkbox and press Space.
  • Go to step 2 and press Back. Is everything as you left it?

🐞 Bug hunt: Travel site sign-up

This demo has 6 hidden bugs. Explore it like a tester, then check your findings.

Found0/6
trips.example.com/join
TripsyStep 1 of 2

Create your account

I agree to the Terms of Service and Privacy Policy

Use the mouse and the keyboard (Tab, Space).

  1. 1

    Hint: Click the words "I agree to the Terms…" instead of the box.

  2. 2

    Hint: Look at the second checkbox before touching anything, then check the summary at the end.

  3. 3

    Hint: On step 2, press Tab until a topic is focused, then press Space.

  4. 4

    Hint: Tick Select all, then untick "Car rental". Look at the parent and the count.

  5. 5

    Hint: Enter a valid email, leave the Terms unticked and press Continue.

  6. 6

    Hint: Tick Terms, untick marketing, continue, then press Back.

How to test it

Checklist

Checkbox test checklist

0 of 13 checked

Example test cases

TC-CB-001Account cannot be created without accepting the Terms

Steps

  1. Open the sign-up page
  2. Enter a valid email
  3. Leave "I agree to the Terms" unticked
  4. Press Continue

Expected result

The user stays on the page. An error text "Accept the Terms to continue" appears next to the checkbox and is announced by the screen reader. No account is created.

TC-CB-002Server rejects sign-up without Terms acceptance

Preconditions

  • Proxy tool or DevTools available

Steps

  1. Fill in the form and tick the Terms
  2. Intercept the sign-up request
  3. Remove or set the termsAccepted field to false
  4. Send the request

Test data

termsAccepted: false

Expected result

The API responds with a 4xx error and no account is created.

TC-CB-003Marketing consent is off by default and respected

Steps

  1. Open the sign-up page
  2. Check the marketing checkbox without touching it
  3. Complete sign-up without ticking it
  4. Open the account's email preferences

Expected result

The marketing box is unticked on load, and the account shows marketing emails as off.

TC-CB-004Parent checkbox shows mixed state

Preconditions

  • Inbox has 5 emails

Steps

  1. Tick "Select all"
  2. Untick one email

Expected result

The parent shows a dash (mixed), the counter reads "4 selected", and Archive acts on exactly 4 emails.

TC-CB-005Ticking every item individually checks the parent

Preconditions

  • Inbox has 5 emails, none ticked

Steps

  1. Tick all 5 emails one by one

Expected result

The parent becomes fully checked and the counter reads "5 selected".

TC-CB-006Label tap toggles the checkbox

Steps

  1. Tap the text "Remember me" (not the box)
  2. Tap it again

Expected result

The box is ticked after the first tap and unticked after the second.

TC-CB-007Checkbox can be operated with the keyboard

Preconditions

  • Web, desktop browser

Steps

  1. Press Tab until the checkbox is focused
  2. Press Space twice

Expected result

A visible focus ring appears. Space ticks and then unticks the box. The page does not scroll.

TC-CB-008Ticks are kept after navigating back

Steps

  1. Tick Terms and untick marketing on step 1
  2. Continue to step 2
  3. Press Back (in-app and with the browser / system back)

Expected result

Step 1 shows exactly the choices the user made: Terms ticked, marketing unticked.

Tip: click a test case to expand it.

Accessibility

Mobile vs web

  • No native checkbox. Multi-select uses checkmarks in lists, selection circles in edit mode, or custom-drawn boxes.
  • For custom boxes, VoiceOver should say something like “Leave at the door, button, selected” or “checkbox, checked” depending on how it’s built. Silence or just “button” is a bug.
  • Test at the largest Dynamic Type sizes: long consent labels must wrap, not truncate.
  • Check that the whole row is tappable, not just the drawn box.
  • Material 3 checkboxes have an 18 dp box inside a 48 dp touch target, and support a tri-state (indeterminate) mode.
    Dev note
    Checkbox (Compose) or CheckBox (Views).
  • In lists, the whole row is usually tappable. Test tapping the text.
    Dev note
    Compose Modifier.toggleable on the row.
  • TalkBack announces “Checked” / “Not checked” plus the label. Test with font scale, display size and dark theme.
  • Watch for state lost after rotation or process death (Don’t keep activities in Developer options helps).
  • Native <input type="checkbox"> looks different in each browser. Custom ones are very common, so check keyboard and ARIA.
  • The required attribute and disabled buttons are client-side only. Make sure the server validates consent too.
  • Test the browser Back button and a page reload: are ticks restored or reset as the spec says?
  • Check indeterminate parents, bulk actions and counts on long, paginated lists (“Select all 50 on this page” vs “all 1,240”).

Check your understanding

Quick quiz

0/5 answered · 0 correct

  1. 1.In a "Choose your pizza toppings" form with an Add to cart button, which control fits best?

  2. 2.You tick "Select all" in an inbox, then untick one email. What should the parent checkbox show?

  3. 3.A sign-up form has "Send me offers by email" ticked by default. What do you do?

  4. 4.A custom checkbox can be focused with Tab, but Space does nothing. Who is affected most?

  5. 5.The Continue button stays disabled until "I agree to the Terms" is ticked. Is that enough?

Key takeaways

  • Checkboxes are independent and usually apply on Submit. Exactly one choice → radio buttons. Instant on/off → toggle switch.
  • States to test: unchecked, checked, mixed, disabled, error, focused, in light and dark mode.
  • A “Select all” parent must always match its children: none = unchecked, some = mixed, all = checked, and counts must agree.
  • The label is part of the target. Tapping the text must toggle the box.
  • Consent boxes must not be pre-ticked, and required boxes must be enforced on the server with a clear, announced error.
  • Custom checkboxes need Space to work, plus the right role and state for screen readers.

Finished this page?Nice work, this page is complete!

Mark it as done to track your progress. It's saved in this browser, no account needed.

Its review cards are now in Bites ⚡
Esc

Type to search the whole site.