23 examples Responsive Uses JS beginner

23 CSS Checkboxes

23 hand-crafted CSS checkboxes — toggles, glow, draw stroke, bouncy pop, glassmorphism, neumorphic, liquid fill, ripple, confetti and more. Every checkbox includes a live demo and a one-click copy snippet.

23 unique checkboxes 20 Pure CSS 3 CSS + JS 0 dependencies
01 / 23
Smooth Slide Toggle
Pure CSS
Pill toggle with gradient fill. The thumb glides on a cubic-bezier curve.
.cb-toggle {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-toggle__input { display: none; }
.cb-toggle__track {
  width: 44px; height: 24px; border-radius: 12px;
  background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.15);
  position: relative;
  transition: background .3s cubic-bezier(.23,1,.32,1),
              border-color .3s;
}
.cb-toggle__thumb {
  position: absolute; top: 3px; left: 3px;
  width: 16px; height: 16px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,.3);
  transition: transform .3s cubic-bezier(.23,1,.32,1);
}
.cb-toggle__input:checked + .cb-toggle__track {
  background: linear-gradient(135deg, #7c6cff, #ff6c8a);
  border-color: transparent;
}
.cb-toggle__input:checked + .cb-toggle__track .cb-toggle__thumb {
  transform: translateX(20px);
}
<label class="cb-toggle">
  <input class="cb-toggle__input" type="checkbox" checked>
  <span class="cb-toggle__track">
    <span class="cb-toggle__thumb"></span>
  </span>
  <span class="cb-toggle__label">Smooth slide toggle</span>
</label>
02 / 23
Neon Glow Checkbox
Pure CSS
Electric box-shadow glow blooms when checked. The checkmark is an inline SVG.
.cb-neon {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-neon__input { display: none; }
.cb-neon__box {
  width: 22px; height: 22px; border-radius: 6px;
  border: 2px solid rgba(124,108,255,.4);
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: all .25s;
}
.cb-neon__input:checked + .cb-neon__box {
  background: #7c6cff;
  border-color: #7c6cff; color: #fff;
  box-shadow:
    0 0 12px rgba(124,108,255,.7),
    0 0 24px rgba(124,108,255,.3);
}
<label class="cb-neon">
  <input class="cb-neon__input" type="checkbox" checked>
  <span class="cb-neon__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="#fff" stroke-width="2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Neon glow on check</span>
</label>
03 / 23
Draw Stroke Checkmark
Pure CSS
The checkmark draws itself using SVG stroke-dashoffset animation on :checked.
.cb-draw {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-draw__input { display: none; }
.cb-draw__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(30,217,138,.35);
  background: rgba(30,217,138,.05);
  display: flex; align-items: center;
  justify-content: center;
  transition: border-color .3s, background .3s;
}
.cb-draw__input:checked + .cb-draw__box {
  border-color: #1ed98a;
  background: rgba(30,217,138,.12);
}
.cb-draw__svg { width: 14px; height: 10px; }
.cb-draw__path {
  stroke-dasharray: 22;
  stroke-dashoffset: 22;
  transition: stroke-dashoffset .35s
    cubic-bezier(.23,1,.32,1) .05s;
}
.cb-draw__input:checked
  + .cb-draw__box .cb-draw__path {
  stroke-dashoffset: 0;
}
<label class="cb-draw">
  <input class="cb-draw__input" type="checkbox" checked>
  <span class="cb-draw__box">
    <svg class="cb-draw__svg" viewBox="0 0 16 12" fill="none">
      <polyline class="cb-draw__path"
        points="1,6 6,11 15,1"
        stroke="#1ed98a" stroke-width="2.2"
        stroke-linecap="round"
        stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Draw stroke checkmark</span>
</label>
04 / 23
Bouncy Pop Checkbox
Pure CSS
An inner dot springs in with cubic-bezier overshoot, giving an elastic tactile feel.
.cb-pop {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-pop__input { display: none; }
.cb-pop__box {
  width: 24px; height: 24px; border-radius: 50%;
  border: 2px solid rgba(245,168,74,.4);
  display: flex; align-items: center;
  justify-content: center;
  transition: border-color .25s;
}
.cb-pop__dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: #f5a84a;
  transform: scale(0);
  transition: transform .4s
    cubic-bezier(.34,1.56,.64,1);
}
.cb-pop__input:checked + .cb-pop__box {
  border-color: #f5a84a;
}
.cb-pop__input:checked
  + .cb-pop__box .cb-pop__dot {
  transform: scale(1);
}
<label class="cb-pop">
  <input class="cb-pop__input" type="checkbox" checked>
  <span class="cb-pop__box">
    <span class="cb-pop__dot"></span>
  </span>
  <span>Bouncy pop checkbox</span>
</label>
05 / 23
Glassmorphism Checkbox
Pure CSS
Frosted glass via backdrop-filter. Checked state fills with a translucent gradient.
.cb-glass {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-glass__input { display: none; }
.cb-glass__box {
  width: 24px; height: 24px; border-radius: 8px;
  background: rgba(255,255,255,.08);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,.2);
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: background .3s, border-color .3s,
              box-shadow .3s, color .3s;
}
.cb-glass__input:checked + .cb-glass__box {
  background: rgba(124,108,255,.4);
  border-color: rgba(124,108,255,.6);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.2);
}
<label class="cb-glass">
  <input class="cb-glass__input" type="checkbox" checked>
  <span class="cb-glass__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Glassmorphism checkbox</span>
</label>
06 / 23
Neumorphic Checkbox
Pure CSS
Dual box-shadows create extrusion. Checked state inverts to a pressed inset.
/* Card background must match: #e0e0e8 */
.cb-neu {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-neu__input { display: none; }
.cb-neu__box {
  width: 26px; height: 26px; border-radius: 8px;
  background: #e0e0e8; color: transparent;
  display: flex; align-items: center;
  justify-content: center;
  box-shadow:
     3px  3px 6px rgba(0,0,0,.18),
    -3px -3px 6px rgba(255,255,255,.7);
  transition: box-shadow .3s, color .3s;
}
.cb-neu__input:checked + .cb-neu__box {
  color: #7c6cff;
  box-shadow:
    inset 2px 2px 5px rgba(0,0,0,.15),
    inset -2px -2px 5px rgba(255,255,255,.6);
}
<!-- Requires a light background on the parent -->
<label class="cb-neu">
  <input class="cb-neu__input" type="checkbox" checked>
  <span class="cb-neu__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="#7c6cff" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Neumorphic checkbox</span>
</label>
07 / 23
Liquid Fill Checkbox
Pure CSS
A flood fill rises from the bottom using scaleY then reveals a white checkmark.
.cb-liquid {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-liquid__input { display: none; }
.cb-liquid__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(61,232,245,.4);
  position: relative; overflow: hidden;
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: border-color .3s, color .3s;
}
.cb-liquid__fill {
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
    #3de8f5, #06b6d4);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform .35s
    cubic-bezier(.23,1,.32,1);
}
.cb-liquid__input:checked + .cb-liquid__box {
  border-color: #3de8f5; color: #fff;
}
.cb-liquid__input:checked
  + .cb-liquid__box .cb-liquid__fill {
  transform: scaleY(1);
}
<label class="cb-liquid">
  <input class="cb-liquid__input" type="checkbox" checked>
  <span class="cb-liquid__box">
    <span class="cb-liquid__fill"></span>
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none"
      style="position:relative;z-index:1">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Liquid fill checkbox</span>
</label>
08 / 23
Rotating Ring Checkbox
Pure CSS
A conic-gradient ring spins in on check. The inner dot scales up simultaneously.
.cb-ring {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-ring__input { display: none; }
.cb-ring__box {
  width: 26px; height: 26px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.1);
  position: relative;
  display: flex; align-items: center;
  justify-content: center;
}
.cb-ring__halo {
  position: absolute; inset: -2px;
  border-radius: 50%;
  background: conic-gradient(
    #7c6cff 0%, #ff6c8a 50%, transparent 50%);
  opacity: 0;
  transition: opacity .3s;
}
.cb-ring__dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: linear-gradient(135deg,#7c6cff,#ff6c8a);
  transform: scale(0);
  transition: transform .35s
    cubic-bezier(.34,1.56,.64,1) .1s;
}
.cb-ring__input:checked
  + .cb-ring__box .cb-ring__halo {
  opacity: 1;
  animation: ring-spin .5s
    cubic-bezier(.23,1,.32,1) forwards;
}
.cb-ring__input:checked
  + .cb-ring__box .cb-ring__dot {
  transform: scale(1);
}
@keyframes ring-spin {
  from { transform: rotate(-90deg); opacity: 0; }
  to   { transform: rotate(0deg);   opacity: 1; }
}
<label class="cb-ring">
  <input class="cb-ring__input" type="checkbox" checked>
  <span class="cb-ring__box">
    <span class="cb-ring__halo"></span>
    <span class="cb-ring__dot"></span>
  </span>
  <span>Rotating ring checkbox</span>
</label>
09 / 23
Brutalist Checkbox
Pure CSS
Hard offset shadow gives physical depth. Checking shifts the box like pressing a button.
/* Card background must be light, e.g. #f0ede5 */
.cb-brute {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-brute__input { display: none; }
.cb-brute__box {
  width: 24px; height: 24px;
  border: 2.5px solid #1a1a1a;
  box-shadow: 3px 3px 0 #1a1a1a;
  background: #fff;
  display: flex; align-items: center;
  justify-content: center;
  font-size: 14px; color: transparent;
  cursor: pointer;
  transition:
    transform .12s, box-shadow .12s,
    background .12s, color .12s;
}
.cb-brute__input:checked + .cb-brute__box {
  background: #1a1a1a; color: #fff;
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 #1a1a1a;
}
<!-- Requires a light background on the parent -->
<label class="cb-brute">
  <input class="cb-brute__input" type="checkbox" checked>
  <span class="cb-brute__box" aria-hidden="true">&#10003;</span>
  <span>Brutalist checkbox</span>
</label>
10 / 23
Gradient Sweep Checkbox
Pure CSS
A rainbow gradient sweeps across the box using background-position animation on check.
.cb-sweep {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-sweep__input { display: none; }
.cb-sweep__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(255,255,255,.15);
  background: rgba(255,255,255,.06);
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: border-color .4s, color .4s;
}
.cb-sweep__input:checked + .cb-sweep__box {
  border-color: transparent; color: #fff;
  background: linear-gradient(90deg,
    #7c6cff, #ff6c8a, #3de8f5, #7c6cff);
  background-size: 200% 100%;
  animation: grad-sweep .6s ease forwards;
}
@keyframes grad-sweep {
  from { background-position: 100% 0; }
  to   { background-position: 0% 0; }
}
<label class="cb-sweep">
  <input class="cb-sweep__input" type="checkbox" checked>
  <span class="cb-sweep__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Gradient sweep checkbox</span>
</label>
11 / 23
3D Flip Checkbox
Pure CSS
The box rotates on the Y axis using rotateY to reveal a checked face.
.cb-flip {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-flip__input { display: none; }
.cb-flip__box {
  width: 26px; height: 26px; border-radius: 7px;
  border: 2px solid rgba(124,108,255,.3);
  perspective: 80px;
  position: relative;
}
.cb-flip__face {
  position: absolute; inset: 0; border-radius: 5px;
  background: #7c6cff;
  display: flex; align-items: center;
  justify-content: center;
  color: #fff; font-size: 14px;
  transform: rotateY(90deg);
  transform-origin: center;
  transition: transform .4s cubic-bezier(.23,1,.32,1);
}
.cb-flip__input:checked
  + .cb-flip__box .cb-flip__face {
  transform: rotateY(0deg);
}
<label class="cb-flip">
  <input class="cb-flip__input" type="checkbox" checked>
  <span class="cb-flip__box">
    <span class="cb-flip__face">&#10003;</span>
  </span>
  <span>3D flip checkbox</span>
</label>
12 / 23
Ripple Wave Checkbox
Pure CSS
A ring expands outward from the checkbox on check using a scale + fade keyframe.
.cb-ripple {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-ripple__input { display: none; }
.cb-ripple__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(255,108,138,.4);
  position: relative; overflow: visible;
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: background .25s, border-color .25s,
              color .25s;
}
.cb-ripple__wave {
  position: absolute; inset: -4px;
  border-radius: 11px;
  border: 2px solid #ff6c8a;
  opacity: 0;
}
.cb-ripple__input:checked + .cb-ripple__box {
  background: #ff6c8a; border-color: #ff6c8a;
  color: #fff;
}
.cb-ripple__input:checked
  + .cb-ripple__box .cb-ripple__wave {
  animation: ripple-out .5s ease-out forwards;
}
@keyframes ripple-out {
  0%   { transform: scale(1);   opacity: .8; }
  100% { transform: scale(1.6); opacity: 0;  }
}
<label class="cb-ripple">
  <input class="cb-ripple__input" type="checkbox" checked>
  <span class="cb-ripple__box">
    <span class="cb-ripple__wave"></span>
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Ripple wave checkbox</span>
</label>
13 / 23
Retro Pixel Checkbox
Pure CSS
An 8-bit checkmark built from SVG rects with crispEdges. Scales in with a pop on check.
.cb-pixel {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-pixel__input { display: none; }
.cb-pixel__box {
  width: 26px; height: 26px;
  border: 3px solid #1ed98a;
  display: flex; align-items: center;
  justify-content: center; overflow: hidden;
  transition: background .25s;
}
.cb-pixel__svg {
  width: 14px; height: 11px;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  opacity: 0; transform: scale(.5);
  transition: opacity .2s,
    transform .3s cubic-bezier(.34,1.56,.64,1);
}
.cb-pixel__input:checked + .cb-pixel__box {
  background: rgba(30,217,138,.15);
}
.cb-pixel__input:checked
  + .cb-pixel__box .cb-pixel__svg {
  opacity: 1; transform: scale(1);
}
<label class="cb-pixel">
  <input class="cb-pixel__input" type="checkbox" checked>
  <span class="cb-pixel__box">
    <svg class="cb-pixel__svg" viewBox="0 0 10 8"
      shape-rendering="crispEdges" fill="#1ed98a">
      <rect x="0" y="4" width="2" height="2"/>
      <rect x="2" y="6" width="2" height="2"/>
      <rect x="4" y="4" width="2" height="2"/>
      <rect x="6" y="2" width="2" height="2"/>
      <rect x="8" y="0" width="2" height="2"/>
    </svg>
  </span>
  <span>Retro pixel checkbox</span>
</label>
14 / 23
Strikethrough Checkbox
Pure CSS
Checking the box strikes through the label text with a sliding underline.
.cb-strike {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-strike__input { display: none; }
.cb-strike__box {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.2);
  background: rgba(255,255,255,.05);
  display: flex; align-items: center;
  justify-content: center; flex-shrink: 0;
  color: transparent; overflow: hidden;
  transition: background .25s, border-color .25s,
              color .25s;
}
.cb-strike__box svg {
  transform: scale(0);
  transition: transform .3s cubic-bezier(.34,1.56,.64,1);
}
.cb-strike__text {
  position: relative; transition: color .3s;
  font-size: 14px;
}
.cb-strike__text::after {
  content: ""; position: absolute;
  left: 0; top: 50%; width: 0; height: 1.5px;
  background: #7c6cff;
  transition: width .35s cubic-bezier(.23,1,.32,1);
}
.cb-strike__input:checked + .cb-strike__box {
  background: #7c6cff; border-color: #7c6cff;
  color: #fff;
}
.cb-strike__input:checked + .cb-strike__box svg {
  transform: scale(1);
}
.cb-strike__input:checked ~ .cb-strike__text {
  color: rgba(255,255,255,.4);
}
.cb-strike__input:checked ~ .cb-strike__text::after {
  width: 100%;
}
<label class="cb-strike">
  <input class="cb-strike__input" type="checkbox" checked>
  <span class="cb-strike__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span class="cb-strike__text">Strikethrough label</span>
</label>
15 / 23
Gooey Blob Checkbox
Pure CSS
A morphing blob shape squishes into view with spring easing when checked.
.cb-blob {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-blob__input { display: none; }
.cb-blob__box {
  width: 28px; height: 28px; border-radius: 8px;
  border: 2px solid rgba(124,108,255,.3);
  display: flex; align-items: center;
  justify-content: center; overflow: hidden;
}
.cb-blob__shape {
  width: 18px; height: 18px;
  background: linear-gradient(135deg, #7c6cff, #ff6c8a);
  border-radius: 0;
  transform: scale(0) rotate(45deg);
  transition: transform .45s cubic-bezier(.34,1.56,.64,1),
              border-radius .45s ease;
}
.cb-blob__input:checked
  + .cb-blob__box .cb-blob__shape {
  transform: scale(1) rotate(0deg);
  border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
}
<label class="cb-blob">
  <input class="cb-blob__input" type="checkbox" checked>
  <span class="cb-blob__box">
    <span class="cb-blob__shape"></span>
  </span>
  <span>Gooey blob checkbox</span>
</label>
16 / 23
Dark Mode Toggle
Pure CSS
Moon-to-sun emoji toggle that shifts between a dark and a warm golden background.
.cb-darkmode {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-darkmode__input { display: none; }
.cb-darkmode__track {
  width: 52px; height: 28px; border-radius: 14px;
  background: #1a1a2e;
  border: 1px solid rgba(255,255,255,.1);
  position: relative; transition: background .4s;
}
.cb-darkmode__thumb {
  position: absolute; top: 4px; left: 4px;
  width: 20px; height: 20px; border-radius: 50%;
  background: #fff; font-size: 11px;
  display: flex; align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0,0,0,.3);
  transition: transform .4s cubic-bezier(.23,1,.32,1);
}
.cb-darkmode__icon::before { content: "\1F319"; }
.cb-darkmode__input:checked + .cb-darkmode__track {
  background: linear-gradient(135deg, #f5a84a, #ffd700);
}
.cb-darkmode__input:checked
  + .cb-darkmode__track .cb-darkmode__thumb {
  transform: translateX(24px);
}
.cb-darkmode__input:checked
  + .cb-darkmode__track .cb-darkmode__icon::before {
  content: "\2600\FE0F";
}
<label class="cb-darkmode">
  <input class="cb-darkmode__input" type="checkbox">
  <span class="cb-darkmode__track">
    <span class="cb-darkmode__thumb">
      <span class="cb-darkmode__icon"></span>
    </span>
  </span>
  <span>Toggle theme</span>
</label>
17 / 23
Pulse Ring Checkbox
Pure CSS
A ring pulses outward from the box on check, like a sonar ping.
.cb-pulse {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-pulse__input { display: none; }
.cb-pulse__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(61,232,245,.3);
  position: relative; overflow: visible;
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: background .25s, border-color .25s,
              color .25s;
}
.cb-pulse__box::after {
  content: ""; position: absolute; inset: -6px;
  border-radius: 13px;
  border: 2px solid #3de8f5; opacity: 0;
}
.cb-pulse__input:checked + .cb-pulse__box {
  background: linear-gradient(135deg, #3de8f5, #06b6d4);
  border-color: #3de8f5; color: #fff;
}
.cb-pulse__input:checked + .cb-pulse__box::after {
  animation: pulse-ring .6s ease-out forwards;
}
@keyframes pulse-ring {
  0%   { transform: scale(1);   opacity: .8; }
  100% { transform: scale(1.5); opacity: 0;  }
}
<label class="cb-pulse">
  <input class="cb-pulse__input" type="checkbox" checked>
  <span class="cb-pulse__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Pulse ring checkbox</span>
</label>
18 / 23
Dash to Check
Pure CSS
An indeterminate dash morphs into a checkmark using border rotation on check.
.cb-dash {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-dash__input { display: none; }
.cb-dash__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(124,108,255,.4);
  background: rgba(124,108,255,.08);
  display: flex; align-items: center;
  justify-content: center;
  transition: border-color .3s, background .3s;
}
.cb-dash__mark {
  width: 10px; height: 2px;
  background: #7c6cff; border-radius: 2px;
  transition: all .35s cubic-bezier(.23,1,.32,1);
}
.cb-dash__input:checked + .cb-dash__box {
  border-color: #7c6cff;
  background: rgba(124,108,255,.18);
}
.cb-dash__input:checked
  + .cb-dash__box .cb-dash__mark {
  width: 12px; height: 12px;
  background: transparent;
  border-right: 2.5px solid #7c6cff;
  border-bottom: 2.5px solid #7c6cff;
  border-radius: 0;
  transform: rotate(45deg) translate(-2px,-3px);
}
<label class="cb-dash">
  <input class="cb-dash__input" type="checkbox" checked>
  <span class="cb-dash__box">
    <span class="cb-dash__mark"></span>
  </span>
  <span>Dash to check</span>
</label>
19 / 23
Multi-State Checkbox
CSS + JS
Three visual states — unchecked, partial (amber), and checked (green) — cycled by JS.
.cb-multi {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
  background: none; border: none; color: #f0eeff;
  font-size: 14px; padding: 0;
}
.cb-multi__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(255,255,255,.2);
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: all .25s cubic-bezier(.23,1,.32,1);
}
.cb-multi__tick {
  transform: scale(0);
  transition: transform .3s cubic-bezier(.34,1.56,.64,1);
}
.cb-multi[data-state="1"] .cb-multi__box {
  background: #f5a84a; border-color: #f5a84a;
  color: #fff;
}
.cb-multi[data-state="1"] .cb-multi__tick {
  transform: scale(.55);
}
.cb-multi[data-state="2"] .cb-multi__box {
  background: #1ed98a; border-color: #1ed98a;
  color: #fff;
  box-shadow: 0 0 14px rgba(30,217,138,.4);
}
.cb-multi[data-state="2"] .cb-multi__tick {
  transform: scale(1);
}
<button class="cb-multi" data-state="0"
  aria-pressed="false">
  <span class="cb-multi__box">
    <svg class="cb-multi__tick" width="12" height="9"
      viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span class="cb-multi__label">Click to cycle</span>
</button>
document.querySelectorAll('.cb-multi').forEach(function(btn) {
  btn.addEventListener('click', function() {
    var s = (parseInt(btn.dataset.state || '0') + 1) % 3;
    btn.dataset.state = s;
    var labels = ['Click to cycle', 'Partial', 'Checked'];
    btn.querySelector('.cb-multi__label').textContent = labels[s];
  });
});
20 / 23
Magnetic Checkbox
CSS + JS
The checkbox box subtly shifts toward the cursor on hover using JS-driven translate.
.cb-magnet {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-magnet__input { display: none; }
.cb-magnet__box {
  width: 26px; height: 26px; border-radius: 8px;
  border: 2px solid rgba(124,108,255,.4);
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: background .25s, border-color .25s,
              color .25s;
  will-change: transform;
}
.cb-magnet__input:checked + .cb-magnet__box {
  background: #7c6cff; border-color: #7c6cff;
  color: #fff;
}
<label class="cb-magnet">
  <input class="cb-magnet__input" type="checkbox" checked>
  <span class="cb-magnet__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Magnetic checkbox</span>
</label>
document.querySelectorAll('.cb-magnet__box').forEach(function(box) {
  box.addEventListener('mousemove', function(e) {
    var r = box.getBoundingClientRect();
    var x = (e.clientX - r.left - r.width  / 2) * 0.3;
    var y = (e.clientY - r.top  - r.height / 2) * 0.3;
    box.style.transform = 'translate(' + x + 'px,' + y + 'px)';
  });
  box.addEventListener('mouseleave', function() {
    box.style.transform = '';
  });
});
21 / 23
Confetti Burst Checkbox
CSS + JS
Coloured dots explode outward from the checkbox the moment it is checked.
.cb-confetti {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
  position: relative;
}
.cb-confetti__input { display: none; }
.cb-confetti__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(255,108,138,.4);
  display: flex; align-items: center;
  justify-content: center; color: transparent;
  transition: background .25s, border-color .25s,
              color .25s;
}
.cb-confetti__input:checked + .cb-confetti__box {
  background: #ff6c8a; border-color: #ff6c8a;
  color: #fff;
}
.cb-dot {
  position: absolute; width: 5px; height: 5px;
  border-radius: 50%; pointer-events: none;
  animation: cb-confetti-burst .55s ease-out forwards;
}
@keyframes cb-confetti-burst {
  0%   { transform: translate(0,0) scale(1); opacity: 1; }
  100% { transform: translate(var(--tx),var(--ty)) scale(0); opacity: 0; }
}
<label class="cb-confetti">
  <input class="cb-confetti__input" type="checkbox">
  <span class="cb-confetti__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span>Click to confetti!</span>
</label>
document.querySelectorAll('.cb-confetti__input').forEach(function(inp) {
  inp.addEventListener('change', function() {
    if (!inp.checked) return;
    var box = inp.nextElementSibling;
    var colors = ['#7c6cff','#ff6c8a','#1ed98a','#f5a84a','#3de8f5'];
    for (var i = 0; i < 8; i++) {
      var dot = document.createElement('span');
      dot.className = 'cb-dot';
      var angle = (i / 8) * 2 * Math.PI;
      var dist = 22 + Math.random() * 14;
      dot.style.cssText =
        'background:' + colors[i % colors.length] + ';' +
        'left:8px;top:8px;' +
        '--tx:' + Math.cos(angle) * dist + 'px;' +
        '--ty:' + Math.sin(angle) * dist + 'px;';
      inp.closest('.cb-confetti').appendChild(dot);
      setTimeout(function(d) { d.remove(); }, 600, dot);
    }
  });
});
22 / 23
Slide-In Label
Pure CSS
A confirmation label slides in from the left when the checkbox is checked.
.cb-slidein {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-slidein__input { display: none; }
.cb-slidein__box {
  width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid rgba(30,217,138,.3);
  display: flex; align-items: center;
  justify-content: center; flex-shrink: 0;
  color: transparent;
  transition: background .25s, border-color .25s,
              color .25s;
}
.cb-slidein__text {
  font-size: 14px; color: #1ed98a;
  max-width: 0; overflow: hidden;
  white-space: nowrap; opacity: 0;
  transition: max-width .4s cubic-bezier(.23,1,.32,1),
              opacity .4s ease;
}
.cb-slidein__input:checked + .cb-slidein__box {
  background: #1ed98a; border-color: #1ed98a;
  color: #fff;
}
.cb-slidein__input:checked ~ .cb-slidein__text {
  max-width: 200px; opacity: 1;
}
<label class="cb-slidein">
  <input class="cb-slidein__input" type="checkbox" checked>
  <span class="cb-slidein__box">
    <svg width="12" height="9" viewBox="0 0 14 11" fill="none">
      <polyline points="1,5.5 5,9.5 13,1"
        stroke="white" stroke-width="2.2"
        stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
  </span>
  <span class="cb-slidein__text">Done!</span>
</label>
23 / 23
Aurora Toggle
Pure CSS
A toggle whose track fills with a shifting aurora gradient when active.
.cb-aurora {
  display: inline-flex; align-items: center;
  gap: 10px; cursor: pointer; user-select: none;
}
.cb-aurora__input { display: none; }
.cb-aurora__track {
  width: 56px; height: 28px; border-radius: 14px;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.12);
  position: relative;
  transition: background .4s, border-color .4s;
}
.cb-aurora__thumb {
  position: absolute; top: 4px; left: 4px;
  width: 20px; height: 20px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,.25);
  transition: transform .4s cubic-bezier(.23,1,.32,1);
}
.cb-aurora__input:checked + .cb-aurora__track {
  background: linear-gradient(90deg,
    #7c6cff, #ff6c8a, #3de8f5, #1ed98a, #7c6cff);
  background-size: 300% 100%;
  border-color: transparent;
  animation: aurora-shift 3s linear infinite;
}
.cb-aurora__input:checked
  + .cb-aurora__track .cb-aurora__thumb {
  transform: translateX(28px);
}
@keyframes aurora-shift {
  0%   { background-position: 0%   50%; }
  100% { background-position: 100% 50%; }
}
<label class="cb-aurora">
  <input class="cb-aurora__input" type="checkbox" checked>
  <span class="cb-aurora__track">
    <span class="cb-aurora__thumb"></span>
  </span>
  <span>Aurora toggle</span>
</label>

Related collections