Description
Lets users select a single value or a min–max range within a defined boundary by dragging one or two handles along a horizontal track.
Filter panels, report configuration screens, and consultation setup forms where users narrow down data by a numeric dimension — for example, filtering stakeholders by engagement score, or setting a budget range for a consultation project.
Many government datasets have continuous numeric dimensions (population counts, satisfaction scores, date offsets) where users need to explore a range rather than enter a precise figure. A slider communicates the bounded nature of the input at a glance and reduces cognitive load compared to a pair of text inputs.
Anatomy
| Part | Required? | Notes |
|---|---|---|
| Track | Required | Horizontal bar representing the full available range. Background uses --op-color-border-default; filled portion uses --op-color-interactive-default. |
| Handle (thumb) | Required | Draggable circular control. Minimum 44×44 px touch target. Receives focus ring on keyboard focus. |
| Fill | Required | Coloured segment of the track between the minimum value (or track start) and the handle, or between two handles in a range slider. |
| Label | Required | Visible text label above the slider. Must not be replaced by placeholder or tooltip alone. |
| Value display | Recommended | Shows the current selected value(s) inline, either adjacent to the label or as a floating tooltip above the active handle. Required when the value is not immediately obvious from context. |
| Min / Max indicators | Optional | Static text or icons at each end of the track showing the boundary values. Helps orient users in contexts where the scale is not self-evident. |
| Tick marks | Optional | Discrete step markers along the track. Use only when the slider is constrained to a small set of meaningful steps (e.g. 1–5 satisfaction rating). |
| Helper text | Optional | Supplementary guidance below the slider. Styled with --op-color-text-secondary. |
| Error message | Optional | Validation message shown in error state. Uses --op-color-status-error and is associated via aria-describedby. |
Variants
Single value
Selects one point on a continuous scale
Use when the user sets a single threshold or target — for example, a minimum engagement score filter or a confidence level threshold.
Range (dual handle)
Selects a min–max band on a continuous scale
Use when the user needs to bound data at both ends — for example, filtering stakeholders by age band or limiting consultation responses to a date offset window.
Stepped
Constrains selection to discrete intervals
Use when only specific values are valid — for example, a 1–10 rating scale or a budget increment of $10,000. Pair with tick marks and a visible step count.
States
| State | Behaviour |
|---|---|
| Default | Track and handle render at rest; fill shows the current value. Value display reflects the initial or previously saved value. |
| Hover | Handle scales up slightly and cursor changes to a grab cursor. Track fill uses --op-color-interactive-hover. No state change occurs until the user begins dragging. |
| Focus | 3px focus ring using --op-color-interactive-focus appears around the handle. Arrow keys adjust the value by one step. Shift+Arrow adjusts by a larger increment (10% of range by default). |
| Active (dragging) | Cursor changes to grabbing. Value display updates live. Handle remains elevated visually to signal it is being manipulated. |
| Disabled | Handle and track render at reduced opacity (--op-color-text-disabled). No interaction is possible. Avoid disabling without explanation — use helper text or a visible reason. |
| Error | Track border and handle outline use --op-color-status-error. Error message appears below the slider. Occurs when a submitted value falls outside a required range defined by business rules. |
| Read-only | Value is visible but the handle cannot be moved. Use when the slider displays a stored value the current user cannot change (e.g. a locked consultation parameter set by an admin). |
Usage guidelines
When to use
- Filtering a stakeholder list by a continuous metric such as engagement score, influence rating, or number of interactions.
- Setting a confidence threshold for automated stakeholder categorisation.
- Configuring a consultation parameter that has a known bounded range (e.g. number of response options: 2–10).
- Letting a community member indicate a preference on a satisfaction or priority scale where approximate values are meaningful.
When not to use
- When an exact numeric value is required — use an Input with type="number" instead, optionally paired with increment/decrement controls.
- When the range is very large or unbounded (e.g. entering a population count from 0 to 10 million) — the precision needed makes a slider impractical.
- When there are only two or three discrete options — use a Radio Group instead.
- When the value must be validated to a strict format (e.g. a dollar amount with cents) — use Input.
Do / Don't
Do
Always show the current value numerically alongside the handle or label so users do not have to estimate.
Don't
Rely on the handle position alone to communicate the selected value — small track widths make this ambiguous.
Do
Provide min and max boundary indicators when the scale is not self-evident from context.
Don't
Omit boundary values on scales that are not universally understood (e.g. an internal scoring model from 0–850).
Do
Use stepped sliders with tick marks when selection must align to meaningful discrete values.
Don't
Apply tick marks to continuous sliders with many possible values — the visual noise adds no meaning.
Do
Write a clear label that names what is being adjusted, e.g. 'Minimum engagement score'.
Don't
Use vague labels like 'Value' or 'Amount' without context.
Do
Ensure the touch target for each handle is at least 44×44 px, even if the handle appears visually smaller.
Don't
Reduce handle size for aesthetic reasons without verifying the touch target remains accessible.
Layout & Spacing
Track height: --op-space-4 (4px) default; --op-space-8 (8px) for high-visibility contexts Handle diameter: 20px visual; touch target padded to 44×44 px Label to track gap: --op-space-8 (8px) Track to value display gap: --op-space-4 (4px) Track to helper text / error message gap: --op-space-8 (8px) Horizontal padding either side of track (to allow handle overhang): --op-space-12 (12px) Min/max indicator to track end gap: --op-space-8 (8px)
Tokens
| Part | Token | Value |
|---|---|---|
| Track (unfilled) | --op-color-border-default | Default resting track background. |
| Track fill | --op-color-interactive-default | Filled portion indicating selected value. Maps to green-400 in the primitive scale. |
| Track fill (hover) | --op-color-interactive-hover | Applied to fill when handle is hovered. |
| Handle background | --op-color-bg-primary | White/light surface so the handle is visually distinct from the track fill. |
| Handle border | --op-color-interactive-default | Matches fill colour to visually connect handle to selected range. |
| Handle focus ring | --op-color-interactive-focus | 3px solid ring. Always visible on keyboard focus. |
| Label text | --op-color-text-primary | Standard label colour. |
| Value display text | --op-color-text-primary | Displayed value must meet 4.5:1 contrast on its background. |
| Min/max indicator text | --op-color-text-secondary | Supplementary — lower visual weight than label and value. |
| Helper text | --op-color-text-secondary | |
| Error message text | --op-color-status-error | Pair with an error icon for colour-independent communication. |
| Error handle border | --op-color-status-error | Replaces interactive-default on the handle border in error state. |
| Disabled track | --op-color-border-default | Opacity reduced to 40%. |
| Disabled handle | --op-color-text-disabled |
Engineering notes
- No wa-* Web Awesome primitive maps directly to a range slider. Implement using a native styled with CSS custom properties, or a custom web component that wraps two native inputs for the dual-handle variant.
- For the dual-handle range variant, use two overlapping elements with z-index management, or a purpose-built accessible range component. Ensure both handles are reachable by keyboard independently.
- Bind the aria-valuenow, aria-valuemin, aria-valuemax, and aria-valuetext attributes dynamically on the handle element (role="slider"). Update aria-valuenow on every input event.
- Use aria-valuetext to provide a human-readable description when the raw number is insufficient — for example, 'High (8 of 10)' for a priority scale.
- Expose a value-change custom event with detail: { value } (single) or detail: { min, max } (range) so consuming pages can react without querying the DOM.
- Respect prefers-reduced-motion: suppress handle scale animations and tooltip transitions when the media query is active.
- Validate that the min handle value never exceeds the max handle value in the range variant. Clamp programmatically on input.
- When rendering inside a form, include a hidden with the resolved value(s) so standard form serialisation works without JavaScript.
Keyboard interaction
| Key | Action |
|---|---|
| Tab | Moves focus to the slider handle (or the first handle in a range slider). |
| Tab (range slider) | Second Tab press moves focus to the second handle. |
| ArrowRight / ArrowUp | Increases value by one step. |
| ArrowLeft / ArrowDown | Decreases value by one step. |
| Shift+ArrowRight / Shift+ArrowUp | Increases value by a larger increment (10% of range or the configured large-step value). |
| Shift+ArrowLeft / Shift+ArrowDown | Decreases value by a larger increment. |
| Home | Sets value to minimum. |
| End | Sets value to maximum. |
Why it matters
Government forms are frequently completed on assistive technology by community members with disabilities, and by public servants using keyboard-only workflows. A slider that cannot be operated by keyboard or that fails to expose its current value to screen readers creates a compliance gap under WCAG 2.1 AA and may exclude users from submitting consultation responses or accessing filtered data.
Focus
Each handle must receive a visible 3px focus ring using --op-color-interactive-focus when navigated to by keyboard. The focus ring must not be clipped by overflow:hidden on a parent container. In a range slider, both handles must be individually focusable and each must display its own focus ring independently. Focus must not jump away from the handle during keyboard value adjustment.
ARIA
| Role or attribute | When to use | Example |
|---|---|---|
role="slider" | Applied to the handle element (or the element that receives keyboard interaction). | <div role="slider" tabindex="0" aria-valuemin="0" aria-valuemax="100" aria-valuenow="45" aria-label="Minimum engagement score"> |
aria-valuemin | The minimum permitted value. Must match the track boundary. | aria-valuemin="0" |
aria-valuemax | The maximum permitted value. Must match the track boundary. | aria-valuemax="100" |
aria-valuenow | The current value. Updated on every input event. | aria-valuenow="45" |
aria-valuetext | Human-readable value description. Use when the numeric value alone is insufficient for understanding. | aria-valuetext="45 — moderate engagement" |
aria-label / aria-labelledby | Associates the visible label text with the handle. Use aria-labelledby when a visible label element is present. | aria-labelledby="engagement-score-label" |
aria-describedby | Associates helper text or error message with the handle. | aria-describedby="engagement-score-help" |
aria-disabled="true" | Applied to the handle when the slider is in disabled state. | aria-disabled="true" |
Contrast
Track fill (--op-color-interactive-default / green-400) on track background (--op-color-border-default): verify at implementation time — the filled track segment is decorative when the value is also shown numerically, but if the fill is the sole value indicator it must meet 3:1 non-text contrast (WCAG 1.4.11). Value display text (--op-color-text-primary) on background (--op-color-bg-primary): must meet 4.5:1 (standard text). Error message text (--op-color-status-error) on background: must meet 4.5:1. Never rely on red colour alone — pair with an icon or prefix text such as "Error:". Min/max indicator text (--op-color-text-secondary) on background: must meet 4.5:1 if it conveys information necessary to use the slider.
Touch targets
Each handle must have a minimum interactive touch target of 44×44 px regardless of the visual handle diameter. Achieve this with padding or a transparent pseudo-element. On mobile viewports used for Social Point public consultations, test with real touch input — CSS :hover states do not fire on touch devices.
Things to avoid
- Do not use colour as the only way to distinguish the filled and unfilled portions of the track — ensure sufficient contrast between fill and track background.
- Do not hide the numeric value entirely and expect users to estimate from handle position.
- Do not place two handles so close together that they become impossible to distinguish and individually target by touch.
- Do not suppress the focus ring for aesthetic reasons — this is a WCAG 2.1 AA failure.
- Do not use placeholder text inside a slider tooltip as a substitute for a proper visible label.