Open demo

CSS code

HTML
<div><span class="lbl">Bordered list</span><div class="chk-list" role="group" aria-label="Project filters">
<label class="chk"><input type="checkbox" checked><span class="bx"></span><span>Include archived projects</span></label>
<label class="chk"><input type="checkbox"><span class="bx"></span><span>Only show my items</span></label>
<label class="chk"><input type="checkbox" checked><span class="bx"></span><span>Group by client</span></label>
</div></div>
<div><span class="lbl">Task list</span><div class="chk-list chk-task" role="group" aria-label="Launch tasks">
<label class="chk"><input type="checkbox" checked><span class="bx"></span><span>Draft the launch copy</span></label>
<label class="chk"><input type="checkbox" checked><span class="bx"></span><span>Export the screenshots</span></label>
<label class="chk"><input type="checkbox"><span class="bx"></span><span>Schedule the announcement</span></label>
</div></div>
<div><span class="lbl">Two-column filters</span><div class="chk-cols" role="group" aria-label="Framework filters">
<label class="chk"><input type="checkbox" checked><span class="bx"></span><span>Bootstrap</span></label>
<label class="chk"><input type="checkbox"><span class="bx"></span><span>Tailwind</span></label>
<label class="chk"><input type="checkbox" checked><span class="bx"></span><span>Plain CSS</span></label>
<label class="chk"><input type="checkbox"><span class="bx"></span><span>Sass</span></label>
<label class="chk"><input type="checkbox"><span class="bx"></span><span>Free only</span></label>
<label class="chk"><input type="checkbox"><span class="bx"></span><span>Updated this year</span></label>
</div></div>
CSS
.chk{position:relative;display:inline-flex;align-items:center;gap:11px;cursor:pointer;font-size:.92rem}
.chk input{position:absolute;opacity:0;width:0;height:0}

.bx{width:20px;height:20px;border:2px solid #64748b;border-radius:6px;position:relative;flex:none;
  transition:background .16s,border-color .16s}
.bx::after{content:"";position:absolute;top:1px;left:6px;width:5px;height:10px;border:solid #fff;
  border-width:0 2px 2px 0;transform:rotate(45deg) scale(0);transition:transform .16s}
.chk input:checked+.bx{background:#16a34a;border-color:#16a34a}
.chk input:checked+.bx::after{transform:rotate(45deg) scale(1)}
.chk input:focus-visible+.bx{outline:2px solid #16a34a;outline-offset:2px}

.chk-list{border:1px solid #e2e8f0;border-radius:12px;background:#fff;overflow:hidden;max-width:440px}
.chk-list .chk{display:flex;padding:13px 17px;border-bottom:1px solid #f1f5f9;width:100%}
.chk-list .chk:last-child{border-bottom:0}
.chk-list .chk:hover{background:#f8fafc}
/* task list: strike through completed items */
.chk-task input:checked~span:last-child{text-decoration:line-through;color:#64748b}
/* two-column filters: CSS columns fill top-to-bottom */
.chk-cols{columns:2;column-gap:34px;max-width:430px}
.chk-cols .chk{display:flex;margin-bottom:11px;break-inside:avoid}

@media(prefers-reduced-motion:reduce){.bx,.bx::after{transition:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div><span class="lbl">Bordered list</span><div class="list-group choice-list" role="group" aria-label="Project filters">
<label class="list-group-item list-group-item-action"><input class="form-check-input" type="checkbox" checked><span>Include archived projects</span></label>
<label class="list-group-item list-group-item-action"><input class="form-check-input" type="checkbox"><span>Only show my items</span></label>
<label class="list-group-item list-group-item-action"><input class="form-check-input" type="checkbox" checked><span>Group by client</span></label>
</div></div>
<div><span class="lbl">Task list</span><div class="list-group choice-list choice-task" role="group" aria-label="Launch tasks">
<label class="list-group-item list-group-item-action"><input class="form-check-input" type="checkbox" checked><span>Draft the launch copy</span></label>
<label class="list-group-item list-group-item-action"><input class="form-check-input" type="checkbox" checked><span>Export the screenshots</span></label>
<label class="list-group-item list-group-item-action"><input class="form-check-input" type="checkbox"><span>Schedule the announcement</span></label>
</div></div>
<div><span class="lbl">Two-column filters</span><div class="choice-cols" role="group" aria-label="Framework filters">
<div class="form-check"><input class="form-check-input" type="checkbox" id="fw1" checked><label class="form-check-label" for="fw1">Bootstrap</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" id="fw2"><label class="form-check-label" for="fw2">Tailwind</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" id="fw3" checked><label class="form-check-label" for="fw3">Plain CSS</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" id="fw4"><label class="form-check-label" for="fw4">Sass</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" id="fw5"><label class="form-check-label" for="fw5">Free only</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" id="fw6"><label class="form-check-label" for="fw6">Updated this year</label></div>
</div></div>
CSS
/* change --choice-accent for the checked colour */
.choice-list,.choice-cols{--choice-accent:#16a34a}
.choice-list .form-check-input,.choice-cols .form-check-input{--bs-form-check-bg:#fff;float:none;margin:0;width:20px;height:20px;flex:none;
  border:2px solid #64748b;border-radius:6px;cursor:pointer;transition:background-color .16s,border-color .16s}
.choice-list .form-check-input:checked,.choice-cols .form-check-input:checked{background-color:var(--choice-accent);border-color:var(--choice-accent)}
.choice-list .form-check-input:focus,.choice-cols .form-check-input:focus{box-shadow:none;border-color:#64748b}
.choice-list .form-check-input:checked:focus,.choice-cols .form-check-input:checked:focus{border-color:var(--choice-accent)}
.choice-list .form-check-input:focus-visible,.choice-cols .form-check-input:focus-visible{outline:2px solid var(--choice-accent);outline-offset:2px}

/* Bootstrap .list-group with actionable rows */
.choice-list{--bs-list-group-bg:#fff;--bs-list-group-border-color:#e2e8f0;--bs-list-group-border-radius:12px;
  --bs-list-group-item-padding-x:17px;--bs-list-group-item-padding-y:13px;
  --bs-list-group-action-color:#1e293b;--bs-list-group-action-hover-color:#1e293b;--bs-list-group-action-hover-bg:#f8fafc;
  --bs-list-group-action-active-color:#1e293b;--bs-list-group-action-active-bg:#f1f5f9;max-width:440px;font-size:.92rem}
.choice-list .list-group-item{display:flex;align-items:center;gap:11px;cursor:pointer;line-height:1.3}
.choice-list .list-group-item:not(:last-child){border-bottom-color:#f1f5f9}
/* task list: strike through completed items */
.choice-task .form-check-input:checked+span{text-decoration:line-through;color:#64748b}
/* two-column filters: CSS columns fill top-to-bottom */
.choice-cols{columns:2;column-gap:34px;max-width:430px;font-size:.92rem}
.choice-cols .form-check{display:flex;align-items:center;gap:11px;padding-left:0;min-height:0;margin:0 0 11px;break-inside:avoid;line-height:1.3}
.choice-cols .form-check-label{cursor:pointer}

@media(prefers-reduced-motion:reduce){.choice-list .form-check-input,.choice-cols .form-check-input{transition:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-slate-500 uppercase">Bordered list</span><div class="max-w-[440px] divide-y divide-slate-100 overflow-hidden rounded-xl border border-slate-200 bg-white" role="group" aria-label="Project filters">
<label class="relative flex w-full cursor-pointer items-center gap-[11px] px-[17px] py-[13px] text-[.92rem] leading-snug hover:bg-slate-50"><input type="checkbox" class="peer sr-only" checked><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Include archived projects</span></label>
<label class="relative flex w-full cursor-pointer items-center gap-[11px] px-[17px] py-[13px] text-[.92rem] leading-snug hover:bg-slate-50"><input type="checkbox" class="peer sr-only"><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Only show my items</span></label>
<label class="relative flex w-full cursor-pointer items-center gap-[11px] px-[17px] py-[13px] text-[.92rem] leading-snug hover:bg-slate-50"><input type="checkbox" class="peer sr-only" checked><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Group by client</span></label>
</div></div>
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-slate-500 uppercase">Task list</span><div class="max-w-[440px] divide-y divide-slate-100 overflow-hidden rounded-xl border border-slate-200 bg-white" role="group" aria-label="Launch tasks">
<label class="relative flex w-full cursor-pointer items-center gap-[11px] px-[17px] py-[13px] text-[.92rem] leading-snug hover:bg-slate-50"><input type="checkbox" class="peer sr-only" checked><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span class="peer-checked:text-slate-500 peer-checked:line-through">Draft the launch copy</span></label>
<label class="relative flex w-full cursor-pointer items-center gap-[11px] px-[17px] py-[13px] text-[.92rem] leading-snug hover:bg-slate-50"><input type="checkbox" class="peer sr-only" checked><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span class="peer-checked:text-slate-500 peer-checked:line-through">Export the screenshots</span></label>
<label class="relative flex w-full cursor-pointer items-center gap-[11px] px-[17px] py-[13px] text-[.92rem] leading-snug hover:bg-slate-50"><input type="checkbox" class="peer sr-only"><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span class="peer-checked:text-slate-500 peer-checked:line-through">Schedule the announcement</span></label>
</div></div>
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-slate-500 uppercase">Two-column filters</span><div class="max-w-[430px] columns-2 gap-x-[34px]" role="group" aria-label="Framework filters">
<label class="relative mb-[11px] flex cursor-pointer items-center gap-[11px] text-[.92rem] leading-snug break-inside-avoid"><input type="checkbox" class="peer sr-only" checked><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Bootstrap</span></label>
<label class="relative mb-[11px] flex cursor-pointer items-center gap-[11px] text-[.92rem] leading-snug break-inside-avoid"><input type="checkbox" class="peer sr-only"><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Tailwind</span></label>
<label class="relative mb-[11px] flex cursor-pointer items-center gap-[11px] text-[.92rem] leading-snug break-inside-avoid"><input type="checkbox" class="peer sr-only" checked><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Plain CSS</span></label>
<label class="relative mb-[11px] flex cursor-pointer items-center gap-[11px] text-[.92rem] leading-snug break-inside-avoid"><input type="checkbox" class="peer sr-only"><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Sass</span></label>
<label class="relative mb-[11px] flex cursor-pointer items-center gap-[11px] text-[.92rem] leading-snug break-inside-avoid"><input type="checkbox" class="peer sr-only"><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Free only</span></label>
<label class="relative mb-[11px] flex cursor-pointer items-center gap-[11px] text-[.92rem] leading-snug break-inside-avoid"><input type="checkbox" class="peer sr-only"><span class="relative size-5 flex-none rounded-md border-2 border-slate-500 transition-[background-color,border-color,color] duration-150 peer-checked:border-green-600 peer-checked:bg-green-600 peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-green-600 after:absolute after:top-[1px] after:left-[6px] after:h-[10px] after:w-[5px] after:scale-0 after:rotate-45 after:border-r-2 after:border-b-2 after:border-white after:transition-[scale] after:duration-150 after:content-[''] peer-checked:after:scale-100 motion-reduce:transition-none motion-reduce:after:transition-none"></span><span>Updated this year</span></label>
</div></div>

About this set

Layouts for longer lists of checkboxes. A bordered list stacks options as full-width rows divided by hairlines, with a hover tint, for filter and settings panels. A task list uses the same rows but strikes through and greys out each item once it is checked, for checklists and to-do lists. A two-column filter panel splits six options into columns with CSS columns, so the order reads down the first column before the second. All the checkboxes use a green checked colour. Every row is a label around a real checkbox hidden without display none, with a sibling span drawing the box, so the whole row is clickable. The strike-through is a sibling selector on the checked input, with no script. The Bootstrap version uses .list-group with .list-group-item-action rows and .form-check-input, the pattern from Bootstrap’s own list-group docs, plus a small columns rule for the filters. The Tailwind version uses divide-y, columns-2 and peer-checked:line-through.

What’s included

  • Bordered list with full-width clickable rows
  • Task list with strike-through on completed items
  • Two-column filter panel using CSS columns
  • Green checked colour, drawn tick
  • No JavaScript

Accessibility

Each row is a label with its visible text as the accessible name, and each list is labelled with role="group" and aria-label. Tab and Space work as for any checkbox, keyboard focus draws a 2px green outline around the box, and completed tasks keep text at 4.5:1 contrast after they are struck through. Tick and colour transitions are disabled under prefers-reduced-motion.

Customise it

Plain CSS: change #16a34a in the .chk input:checked+.bx rule and the padding on .chk-list .chk. Bootstrap: set --choice-accent and the --bs-list-group-* variables on .choice-list. Tailwind: swap green-600 in the peer-checked: classes and px-[17px] py-[13px] on the rows.