Components · Forms & selection
Slider
Custom-styled range slider with a visible fill bar and prominent thumb. Distinct from the native Range component. Extracted from zetta-form-v1_3.md (removed in v1.5) as a standalone file in v1.4.
Preview
Build with the skill
No package to install — hand this to your AI to generate or migrate the component in your stack.
Apply the Zetta "Slider" component to this project using the zetta-design-md skill.
WHEN TO USE
- Migrating or fixing existing code (the common case): audit the current implementation against the `slider` spec and CORRECT every deviation — replace off-spec values, don't only add new ones.
- New component: build it to the `slider` spec in this project's stack.
AUDIT & FIX (when the component already exists)
Compare it to the skill's spec and fix, don't just append: hardcoded colors/hex, off-scale radius, wrong fonts, dark/navy fills, shadows used in place of borders (or missing borders), brand lime used as a CTA or interaction (must be primary indigo), and any missing or wrong hover / focus / active / disabled / invalid state or missing 2px focus ring. Replace each with the correct Zetta token.
ALWAYS
- Pull the authoritative spec and tokens from the skill — never guess or hardcode values.
- Use this project's own component conventions and framework idioms.
- Honor the Zetta guardrails (brand = identity only, primary = interaction, shadows for overlays) and verify in Light, Dark, and Accessibility. Anatomy & rules
●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━●
↑ thumb (20×20, canvas/primary) ↑
════════════ ← slider-range (primary)
───────────────────────────────── ← slider-track (surface-muted, 6px)
↑ paddingY: 19px expands hit area past 44px minimum
| State | Track | Range fill | Thumb |
|---|---|---|---|
| Default | {colors.surface-muted} |
{colors.primary} |
Canvas fill, primary border, shadow |
| Hover | Unchanged | Unchanged | Scale 1.1 |
| Focus | Unchanged | Unchanged | 2px solid {colors.border-focus} outline |
| Active (dragging) | Unchanged | Unchanged | Scale 1.15, primary-bg fill |
| Disabled | {colors.disabled-bg} |
{colors.disabled-text} |
Disabled border, not-allowed, 50% opacity |
When to use
- Adjusting a value within a known range where precision is less important than the relative position: volume, opacity, zoom, budget.
- Settings panels where the user needs a visual feel for the value relative to the full range.
When not to use
- Precise numeric entry — use Number Input.
- Selecting from a small set of steps (2–5) — use Radio buttons.
- Compact or inline context — use Range.
Do
- Always show the current value — either as a thumb tooltip during drag, or as a read-only number input alongside the slider.
- Set meaningful
min,max, andstepvalues with units in the label. - Allow the user to also type a precise value in an adjacent Number Input for power users.
Don't
- Don't use slider without visible min/max labels or value display.
- Don't use slider for values with more than 3–4 significant steps of difference — the thumb is too imprecise.
- Label: noun + unit in parentheses. "Opacity (%)", "Budget (USD)", "Volume".
- Min/max labels: show at the ends of the track — numeric value or descriptive ("Min" / "Max", "Quiet" / "Loud").
- Thumb tooltip: show the current value during drag. Format matches the field unit: "75%", "$1,200", "0.5".
- Error message: "Value must be between [min] and [max]." — only shown when value is set programmatically outside range.
Keyboard
| Key | Behavior |
|---|---|
Tab |
Move focus to the slider thumb |
Left / Down Arrow |
Decrease value by step |
Right / Up Arrow |
Increase value by step |
Page Down |
Decrease value by step × 10 |
Page Up |
Increase value by step × 10 |
Home |
Set to min |
End |
Set to max |
Accessibility
- ARIA role:
role="slider"on the thumb element. aria-valuenow— current value (numeric, not formatted string).aria-valueminandaria-valuemax— define the range.aria-valuetext— human-readable formatted value: "75 percent", "$1,200". Required whenaria-valuenowalone is ambiguous.aria-labeloraria-labelledbyon the thumb — must name the control, not just the value.aria-disabled="true"when disabled.- Hit area:
paddingY: 19pxon the track expands the interactive area to meet the 44px minimum touch target. - Contrast: Primary-colored fill against
{colors.surface-muted}track is visually clear but semantically backed byaria-valuenow— no contrast requirement applies to the fill indicator itself.
Spec
Values and token references resolved straight from the Zetta spec.
slider-track
- backgroundColor
- {colors.surface-muted}
- height
- 6px
- borderRadius
- {rounded.full}
- position
- relative
- display
- flex
- alignItems
- center
- cursor
- pointer
- paddingY
- 19px
slider-range
- backgroundColor
- {colors.primary}
- height
- 100%
- borderRadius
- {rounded.full}
- position
- absolute
slider-thumb
- backgroundColor
- {colors.canvas}
- borderColor
- {colors.primary}
- borderWidth
- 2px
- width
- 20px
- height
- 20px
- borderRadius
- {rounded.full}
- shadow
- {elevation.shadow.raised}
- position
- absolute
- top
- 50%
- transform
- translateY(-50%)
- cursor
- pointer
- transition
- transform {motion.duration-fast}
slider-thumb-hover
- transform
- translateY(-50%) scale(1.1)
slider-thumb-focus
- outline
- 2px solid {colors.border-focus}
- outlineOffset
- 2px
slider-thumb-active
- transform
- translateY(-50%) scale(1.15)
- backgroundColor
- {colors.primary-bg}
slider-disabled
- cursor
- not-allowed
- opacity
- 0.5
slider-track-disabled
- backgroundColor
- {colors.disabled-bg}
slider-range-disabled
- backgroundColor
- {colors.disabled-text}
slider-thumb-disabled
- borderColor
- {colors.disabled-text}
- cursor
- not-allowed