ComponentsSlider

Slider

atom

A drag-to-set value control on a stroke-3 track with a precise handle.

Display
Brightness62%
Volume40%
Bass · locked30%

Recipe CSS

This is the exact CSS your kit ships for Slider — token-driven, so it re-themes with every knob. Get it (and the rest) from the configurator's Use kit panel.

/* === Slider === */
/* Slider track is stroke-3 (3px): light enough to read as a control,
 * heavy enough to grab. Pairs with the 6px progress fill — they read as
 * "sibling controls" because they share the stroke vocabulary. */
.slider {
  width: 100%;
  height: var(--k-stroke-3, 3px);
  background: var(--k-track, var(--k-surface-2));
  border-radius: 999px;
  position: relative;
}
/* Uses --k-fill so gradient mode flows along the track without affecting the knob.
   display:block is REQUIRED — the markup is a <span> (inline), so without it the
   width:%/height:100% are ignored and the fill renders 0×0 (no coloured range). */
.slider__fill { display: block; height: 100%; background: var(--k-fill, var(--k-primary)); border-radius: 999px; }
.slider__knob {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  /* Size GROWS with the Scale control (14/16/20), parallel to the toggle. */
  width: var(--k-slider-knob, 16px);
  height: var(--k-slider-knob, 16px);
  /* ALWAYS round — a slider thumb is a "round handle" metaphor, shape-locked
     like the toggle knob + radio (it does NOT follow Box radius; squaring it
     while the toggle stays round read inconsistent). */
  border-radius: 50%;
  /* White/surface fill + 2px brand rim — shadcn's slider thumb reads as a
     precise mechanical handle, not a filled bullet. Selection wraps it in the
     soft --k-ring-halo on top of the rim. */
  background: var(--k-surface);
  border: 2px solid var(--k-primary);
  box-shadow: var(--k-shadow-sm);
  transition: width var(--k-dur-fast, 120ms) var(--k-ease, ease),
              height var(--k-dur-fast, 120ms) var(--k-ease, ease),
              box-shadow var(--k-dur-fast, 120ms) var(--k-ease, ease);
}
/* Interactive states — the knob reacts like a live control. Hover/focus/drag
   wrap it in the SAME soft halo (--k-ring-halo) the form fields use on focus,
   and grabbing it (keyboard focus or active drag) grows the knob a touch. The
   track itself carries role="slider" tabindex, so we suppress its default
   outline and put the focus signal on the knob instead (shadcn pattern). */
.slider:hover .slider__knob {
  box-shadow: var(--k-shadow-sm), 0 0 0 var(--k-ring-w) var(--k-ring-halo);
}
.cockpit-preview .slider:focus-visible { outline: none; }
/* Selection = ONLY the soft halo (--k-ring-halo) around the knob — the SAME
   halo a focused field gets. The knob keeps its normal (white) ring; we do NOT
   recolour the border (that turned the knob into a big solid disc, esp. in mono
   themes where --k-ring is near-black). Halo persists on :focus and fires
   through the drag via :active / .slider--grabbing. */
.slider:focus .slider__knob,
.slider:active .slider__knob,
.slider--grabbing .slider__knob {
  width: calc(var(--k-slider-knob, 16px) + 2px);
  height: calc(var(--k-slider-knob, 16px) + 2px);
  /* LITERALLY the input focus-halo — same as `.in:focus` (mail input): just the
     --k-ring-halo band, nothing else. No drop shadow, no border, no white. */
  box-shadow: 0 0 0 var(--k-ring-w) var(--k-ring-halo);
}
/* Disabled — dimmed + non-interactive (shadcn parity: opacity-50 +
   pointer-events-none). The component also drops tabindex and the handlers. */
.slider--disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}