Menu

HTML Checkbox: Checked, Values, Groups and Custom Styles

How to make a checkbox in HTML with <input type="checkbox">: labels, the checked attribute, what the form sends when it is checked and when it is not, groups of checkboxes, select all with the indeterminate state, and styling.

This page includes runnable editors - edit, run, and see output instantly.

How to make a checkbox in HTML

A checkbox is an <input type="checkbox">. Put it inside a <label> with its text, so clicking the text toggles it too. Tick one or both boxes and press Save to see what the form sends:

With the default state the form sends only updates=on. Two rules explain it:

  • A checked box sends name=value. The second box has no value, so it sends the default, on.
  • An unchecked box sends nothing at all. Not newsletter=no, not an empty value: the name is missing from the data.

checked in the HTML sets the starting state. Like every boolean attribute, its presence is what counts: checked="false" still checks the box.

Checkbox attributes

AttributeDoes
nameThe key sent when checked
valueWhat is sent when checked (default on)
checkedChecked when the page loads
requiredThe form will not submit until this box is checked
disabledCannot be toggled and is not sent

A group of checkboxes

For "pick any of these", give every box the same name and a different value. Wrap them in a <fieldset> with a <legend> so the group has a name:

The form sends topic=html and topic=css: the same name twice. Most server frameworks can read that as a list. PHP is the exception: it keeps only the last one unless the name ends in brackets, name="topic[]". In JavaScript, new FormData(form).getAll('topic') returns ['html', 'css'].

Sending a value when the box is unchecked

When the server needs an explicit "no", put a hidden input with the same name before the checkbox. Unchecked, only the hidden value is sent; checked, both are sent and the server takes the last one:

Press Continue: the form refuses until the terms box is ticked, because it is required. Then it sends marketing=no and terms=accepted, or marketing=no, marketing=yes and terms=accepted with the first box ticked. Frameworks such as Rails generate exactly this hidden-input pair. Check how your server reads a repeated name before relying on it.

Select all and the indeterminate state

A checkbox has a third look, a dash, for "some but not all". It exists only in JavaScript: set box.indeterminate = true. A "select all" box uses it when some of the boxes it controls are checked:

indeterminate only changes the look (and what screen readers announce: "mixed" or "partially checked"). The box is still either checked or unchecked underneath, and that is what the form sends. Clicking an indeterminate box clears the dash and toggles it.

Use the change event to react to a checkbox, and read box.checked for its state. box.value does not change when the box is toggled.

Styling checkboxes

The quickest change is accent-color, which recolors the native checkbox and keeps all its behavior. For a completely different look, appearance: none removes the native drawing and lets you style the input like any box:

The custom box is still a real checkbox: it toggles on click and Space, is sent with the form, and is announced as a checkbox. Draw it with :checked and keep a :focus-visible style, because without the native drawing there is no focus ring you did not add yourself.

A toggle switch

A switch is a checkbox that means "on/off right now" rather than "include this". Draw it with appearance: none and add role="switch" so screen readers announce a switch that is on or off instead of a checkbox that is checked:

inset-inline-start places the knob from the start of the line, so the switch slides the other way on right-to-left pages, as it should. For grouped yes/no choices where only one can be picked, see HTML radio button.

Common mistakes

  • Expecting false for an unchecked box. Nothing is sent. Handle a missing name as "off" on the server, or add the hidden input.
  • checked="false". It still checks the box. Remove the attribute.
  • A checkbox with no label, or with text next to it that is not a <label>. The small box becomes the only click target and screen readers announce "checkbox" with no name. See HTML label.
  • Forgetting value, so every box in a group sends on and the server cannot tell them apart.
  • Reading box.value to see if it is checked. Use box.checked.
  • Checkboxes for "choose one". That is what radio buttons are for.

Frequently Asked Questions

How do you make a checkbox in HTML?

Use <input type="checkbox"> inside a label: <label><input type="checkbox" name="terms" value="yes"> I agree</label>. The label makes the text clickable too.

How do I make a checkbox checked by default?

Add the checked attribute: <input type="checkbox" name="news" checked>. Its presence is what counts, so checked="false" still checks it. In JavaScript, set box.checked = true or false.

What value does an unchecked checkbox send?

None. An unchecked checkbox is left out of the submitted data entirely. A checked one sends its value, or on if it has no value. If the server needs an explicit "no", put a hidden input with the same name before the checkbox.

How do I get the value of a checkbox in JavaScript?

Read box.checked, which is true or false. box.value is the value it would send, and it stays the same whether the box is checked or not. Listen for the change event to react when it is toggled.

How do I change the color of a checkbox?

Set accent-color on it: input[type=checkbox] { accent-color: #16a34a; }. For a fully custom look, set appearance: none and draw the box and the check mark yourself with CSS.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED