Before building Checkbox Style Generator, we ran a small, direct test on the two most common ways developers hide a native checkbox to replace it with a custom-styled one.
We called .focus() on both. Only one worked.
We created two checkboxes: one hidden with display: none, one hidden with opacity: 0 (plus positioning to keep it out of the visual flow). Calling .focus() on the display:none checkbox did nothing — document.activeElement never changed. The opacity:0 checkbox focused normally. That's not a subtle difference: it's the difference between a keyboard user being able to reach your custom checkbox at all, or not.
Why this keeps happening
display:none feels like the obvious way to "hide" something — it's the first property most people reach for. But it removes the element from the accessibility tree and the tab order entirely, which is exactly why multiple independent accessibility write-ups (from design-system teams to dedicated a11y guides) call this out as one of the most common custom-checkbox mistakes. This tool's generated CSS always uses opacity:0 instead, so that mistake isn't something you have to remember to avoid.
Focus rings and indeterminate state, included
Since the native input stays focusable, this tool also styles it properly: a visible :focus-visible outline appears on the custom box when the hidden input is focused, and the :indeterminate state (used for a parent checkbox when only some children are checked) gets its own look — both included by default, not left for you to add later.