Skip to content
Caseroom

Components · Forms

Checkbox

A native checkbox in the Caseroom style. No JavaScript.

0.34% of the 2,062 sites in The UI Index have a checkbox (7 sites).

Both previews render the same markup; the HTML tab below is that markup without a framework.

Install

React
npx shadcn@latest add https://www.themes.dev/caseroom/r/checkbox.json
Astro
npx shadcn@latest add https://www.themes.dev/caseroom/r/astro/checkbox.json

Or copy the files below into your project. They need clsx, tailwind-merge, and the Caseroom theme. The HTML needs only the compiled CSS.

checkbox.tsx
import type { InputHTMLAttributes } from 'react';
import { cn } from '@/lib/utils';
import { CHECK_PATH, checkboxClasses, checkboxMark, checkboxWrap } from './checkbox.variants';

export type CheckboxProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;

/** A native checkbox: works in forms, with the keyboard and without JavaScript. Pair it with a Label. */
export function Checkbox({ className, ...props }: CheckboxProps) {
  return (
    <span className={cn(checkboxWrap, className)}>
      <input type="checkbox" className={checkboxClasses} {...props} />
      <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className={checkboxMark}>
        <path d={CHECK_PATH} />
      </svg>
    </span>
  );
}
checkbox.variants.ts
export const checkboxWrap = 'relative inline-flex size-4 shrink-0';
export const checkboxClasses =
  'peer size-4 shrink-0 cursor-pointer appearance-none rounded-[4px] border border-input bg-background transition-[color,background-color,border-color,transform] enabled:not-checked:hover:border-foreground enabled:not-checked:hover:bg-accent enabled:active:scale-90 enabled:not-checked:active:bg-pressed checked:border-primary checked:enabled:hover:border-[color-mix(in_oklab,var(--primary)_var(--hover-amount),var(--background))] checked:enabled:hover:bg-[color-mix(in_oklab,var(--primary)_var(--hover-amount),var(--background))] checked:enabled:active:border-[color-mix(in_oklab,var(--primary)_var(--press-amount),var(--press-mix))] checked:enabled:active:bg-[color-mix(in_oklab,var(--primary)_var(--press-amount),var(--press-mix))] checked:bg-primary indeterminate:border-primary indeterminate:bg-primary disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive';
export const checkboxMark =
  'pointer-events-none absolute inset-0 hidden size-4 text-primary-foreground peer-checked:block';
export const CHECK_PATH = 'M3.5 8.5l3 3 6-7';