Skip to content
ZeroServer.tools

CSS Checkbox Generator

Generate custom CSS checkbox styles with live preview. No images or icon fonts needed.

Presets
#94a3b8
#22d3ee
#ffffff
Live Preview
Size: 20pxStroke: 2pxStyle: checkRadius: 3px

Click to toggle

<label style="display:flex;align-items:center;gap:8px;cursor:pointer">
  <input type="checkbox" class="custom-checkbox">
  Checkbox label
</label>
/* Custom Checkbox */
input[type="checkbox"].custom-checkbox {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 20px;
  height: 20px;
  border: 2px solid #94a3b8;
  border-radius: 3px;
  background-color: transparent;
  cursor: pointer;
  vertical-align: middle;
  transition: border-color 0.15s, background-color 0.15s;
}

input[type="checkbox"].custom-checkbox:focus-visible {
  outline: 2px solid var(--color-primary, #3b82f6);
  outline-offset: 2px;
}

input[type="checkbox"].custom-checkbox:checked {
  background-color: #22d3ee;
  border-color: #22d3ee;
}

input[type="checkbox"].custom-checkbox:checked::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 2px;
  width: 5px;
  height: 10px;
  border: 2px solid #ffffff;
  border-top: none;
  border-left: none;
  transform: rotate(45deg);
}

How to style CSS checkboxes

Custom checkboxes use appearance: none to remove the OS default, then rebuild the box with CSS borders and the ::after pseudo-element for the check mark. The :checked selector switches the background and reveals the mark. This technique requires no images, SVG, or JavaScript and works across all modern browsers.

Built and maintained by Meet Shah · Last updated

What this tool is used for

  • Producing a styled checkbox without a component library.
  • Getting a custom check mark with a live preview.
  • Matching a checkbox's size and colour to a design.
  • Producing a checkbox that matches an existing radio or switch in the same form.
  • Comparing two check-mark treatments side by side.

Frequently Asked Questions

How is a checkbox styled without losing accessibility?
By keeping the real `<input type="checkbox">` in the DOM and styling it, or hiding it visually while styling a sibling. What must not happen is replacing it with a `<div>` — that loses keyboard operation, the checked state, and every assistive-technology affordance.
What does appearance: none do?
Removes the browser's native control rendering so your own styles apply. It is the modern approach and it takes the focus ring with it, so a replacement focus style is not optional — an unstyled `appearance: none` checkbox is invisible to keyboard users.
How is the checked state styled?
With the `:checked` pseudo-class, and `:indeterminate` for the third state a parent checkbox uses. Indeterminate can only be set from JavaScript, never from markup, which is why a tri-state list needs a script even when nothing else on the page does.
Why hide the input rather than remove it?
Because it carries the semantics. `opacity: 0` with a real size, or a clipping technique, keeps it focusable and announced while letting a sibling element carry the visuals. `display: none` removes it from the accessibility tree and from the tab order entirely.
How large should the target be?
At least 44×44 CSS pixels including the label, which is the WCAG target-size guidance. A 16px box alone is a difficult touch target, which is why wrapping the input in a `<label>` — making the text clickable too — is worth doing regardless of styling.

Common errors and gotchas

  • Hiding the real input with `display: none`, which removes it from the keyboard tab order entirely.
  • Styling the box but not the checked state's contrast, which leaves the tick hard to see.
  • Using a div rather than a real input, which loses every built-in role and behaviour.
  • Forgetting the indeterminate state, which some forms need.
  • Making the hit area smaller than the recommended minimum for touch.

Related Design & CSS tools

Private & free — this tool runs entirely in your browser.

KinstaFast managed hosting — up to $500 + 10% recurring.affiliate