simpletool.io

CSS Checkbox Generator

Customised native checkbox styling with accessibility preserved.

Rendering runs in your browser.
CSS + HTML
<label class="custom-checkbox">
  <input type="checkbox" checked />
  <span class="box"></span>
  <span>Subscribe to updates</span>
</label>

<style>
.custom-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}
.custom-checkbox input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.custom-checkbox .box {
  position: relative;
  display: inline-block;
  width: 24px;
  height: 24px;
  background: #FFFFFF;
  border: 1px solid #E3E8EE;
  border-radius: 6px;
  transition: background 150ms, border-color 150ms;
}
.custom-checkbox input:checked + .box {
  background: #635BFF;
  border-color: #635BFF;
}
.custom-checkbox input:focus-visible + .box {
  box-shadow: 0 0 0 3px #635BFF33;
}
.custom-checkbox input:checked + .box::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 4px;
  width: 5px;
  height: 11px;
  border: solid #FFFFFF;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
</style>

What is a CSS Checkbox Generator?

A CSS checkbox generator produces styled, brand-matched checkboxes without sacrificing the native <input type="checkbox"> element's behaviour. The trick is to hide the native input visually (not with display: none, which would break keyboard access) while keeping it in the layout, then style a sibling <span> to look like a custom checkbox. When the user clicks the label, the browser toggles the native input and CSS sibling selectors (:checked + .box) restyle the visible box.

Keep the native input alive. Replacing it with a div destroys form submission, keyboard focus (Tab / Space), screen-reader announcements, the :checked pseudo-class, and the browser's built-in indeterminate state. The generator's pattern hides the input with position: absolute; opacity: 0 so it remains focusable and submittable, then draws the visual box as a pure-CSS sibling.

Focus visibility. The generator adds a focus ring via :focus-visible (not :focus), which shows the ring for keyboard users but not for mouse clicks — the modern accessibility best practice. Users who tab in can see exactly where keyboard focus is; users who click don't get distracting rings.

Check-mark options. Tick uses two CSS borders rotated to form a checkmark — the most recognisable. Dot is a filled circle, appropriate for single-selection toggles that technically use a checkbox ("Remember me" is an example). Cross is a rotated-lines X, occasionally used in deletion/removal UIs. Pick based on semantic expectation: tick for "completed", dot for "active", cross for "excluded".

Sizing. The default 24px is comfortable for desktop UI. Mobile targets should be at least 44×44px of clickable area (the wrapper <label>provides this even when the visual box is smaller). Don't go below 20px on any device — small checkboxes are disproportionately error-prone.

Animation. The generator transitions background and border colour over 150ms, which feels responsive without being slow. For a springier feel, add atransition on transform and scale(1.1) briefly on check. For a more muted feel, drop the transition entirely.

How to generate a styled CSS checkbox

  1. Pick a shape (square, rounded, circle) and check-mark style.
  2. Set size and colours to match your design system.
  3. Copy the HTML + CSS and paste into your component library.
  4. Wrap with a label and matching text — the whole label becomes clickable.

Features

  • Native input preserved for keyboard, focus, form submission.
  • Three shapes and three check-mark styles.
  • Per-state colour control: checked, unchecked, border, mark.
  • Focus-visible ring for accessibility.
  • Copy-ready HTML + CSS snippet.

Frequently asked questions

Why hide the native checkbox?
The native input is ugly to style directly across browsers. Hiding it (with opacity: 0, not display: none) preserves keyboard access, form submission, and screen-reader behaviour while letting us style a sibling element to look custom.
Does this work with screen readers?
Yes. The native input is still in the DOM and focusable — screen readers announce it as a checkbox. Just make sure the <label> wrapper has descriptive text next to the visual box.
How do I handle indeterminate state?
Native checkboxes support indeterminate via JavaScript (input.indeterminate = true). You can add a CSS rule on :indeterminate to show a dash or half-fill on the visual box.
Can I use this in forms?
Yes — the native input still participates in form submission because it's present in the DOM, just visually hidden.