slider
The slider element can be used for numeric input. Optional labels can be displayed on the left or the right.
It also has an optional tooltip which is displayed on top of the slider thumb when the mouse is over it. The tooltip can either display the absolute or relative value and an optional unit.
As the slider uses the native input element, all attributes for this element are supported for the slider as well.
Each
In other words, according to the Web Content Accessibility Guidelines (WCAG), it is highly recommended to use only one
input
can be referenced by multiple labels
, but the input
tag has a unique id
that can be paired to only one label
(through its same for attribute).In other words, according to the Web Content Accessibility Guidelines (WCAG), it is highly recommended to use only one
label
together with the input
.
When
aria-valuenow
holds a value that isn't comprehensible to the user, such as representing the day of the week with a numerical value, the user needs to set the aria-valuetext
attribute as a string providing a clear description of the slider's value, like "Monday," to enhance user understanding.
table of content
- description
- component variations
- Standard slider
- Standard slider disabled
- Standard slider with tooltip
- Standard slider with left label
- Standard slider with right label
- Standard slider with left and right label
- Standard slider with absolute value tooltip
- Standard slider with absolute value tooltip and unit
- Standard slider with label left top
- Standard slider with label right top
- Standard slider with label left and right top
- Standard slider with label left and right top, without tooltip
- slider vertical
- slider vertical disabled
- slider vertical with tooltip
- slider vertical with label
- slider vertical with absolute value tooltip
- slider vertical with absolute value tooltip and unit
- style scss
component variations
Standard slider
<div class="a-slider">
<input
tabindex="0"
id="slider1"
type="range"
min="0"
max="100"
step="1"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-orientation="horizontal"
aria-label="a standard slider"
aria-description="here goes an extensive description text"
value="50"
/>
</div>
Standard slider disabled
<div class="a-slider">
<input
tabindex="0"
id="slider2"
type="range"
min="0"
max="100"
step="1"
disabled=""
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-orientation="horizontal"
aria-label="a standard slider disabled"
aria-description="here goes an extensive description text"
value="50"
/>
</div>
Standard slider with tooltip
<div class="a-slider">
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="relative"
aria-haspopup="false"
>
50 %
</span>
<input
tabindex="0"
id="slider3"
type="range"
min="0"
max="100"
step="1"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-orientation="horizontal"
aria-label="a standard slider with a tooltip"
aria-description="here goes an extensive description text"
value="50"
/>
</div>
</div>
Standard slider with left label
<div class="a-slider">
<label for="slider4">Label</label>
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="relative"
aria-haspopup="false"
>
50 %
</span>
<input
tabindex="0"
id="slider4"
type="range"
min="0"
max="100"
step="1"
aria-labelledby="a standard slider with left label"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-orientation="horizontal"
aria-description="here goes an extensive description text"
value="50"
/>
</div>
</div>
Standard slider with right label
<div class="a-slider">
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="relative"
aria-haspopup="false"
>
50 %
</span>
<input
tabindex="0"
id="slider5"
type="range"
min="0"
max="100"
step="1"
aria-labelledby="a standard slider with right label"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-orientation="horizontal"
aria-description="here goes an extensive description text"
value="50"
/>
</div>
<label for="slider5">Label</label>
</div>
Standard slider with left and right label
<div class="a-slider">
<label for="slider6">Left</label>
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="relative"
aria-haspopup="false"
>
50 %
</span>
<input
tabindex="0"
id="slider6"
type="range"
min="0"
max="100"
step="1"
aria-labelledby="a standard slider with both labels"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-orientation="horizontal"
aria-description="here goes an extensive description text"
value="50"
/>
</div>
<label for="slider6">Right</label>
</div>
Standard slider with absolute value tooltip
<div class="a-slider a-slider--unitless">
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="absolute"
aria-haspopup="false"
>
501
</span>
<input
tabindex="0"
id="slider7"
type="range"
min="1"
max="1000"
step="1"
aria-valuemin="1"
aria-valuemax="1000"
aria-valuenow="501"
aria-orientation="horizontal"
aria-label="a standard slider with a tooltip with absolute value"
aria-description="here goes an extensive description text"
value="501"
/>
</div>
</div>
Standard slider with absolute value tooltip and unit
<div class="a-slider">
<label for="slider8">Degrees</label>
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="absolute"
tooltip-unit="°"
aria-haspopup="false"
>
181°
</span>
<input
tabindex="0"
id="slider8"
type="range"
min="1"
max="360"
step="1"
aria-labelledby="a standard slider with a tooltip with absolute value and unit"
aria-valuemin="1"
aria-valuemax="360"
aria-valuenow="181"
aria-orientation="horizontal"
aria-description="here goes an extensive description text"
value="181"
/>
</div>
</div>
Standard slider with label left top
<div class="a-slider a-slider--labels-on-top">
<label for="slider9">Degrees</label>
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="absolute"
tooltip-unit="°"
aria-haspopup="false"
>
181°
</span>
<input
tabindex="0"
id="slider9"
type="range"
min="1"
max="360"
step="1"
aria-labelledby="a standard slider with a label on the top left"
aria-valuemin="1"
aria-valuemax="360"
aria-valuenow="181"
aria-orientation="horizontal"
aria-description="here goes an extensive description text"
value="181"
/>
</div>
</div>
Standard slider with label right top
<div class="a-slider a-slider--labels-on-top">
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="absolute"
tooltip-unit="°"
aria-haspopup="false"
>
181°
</span>
<input
tabindex="0"
id="slider10"
type="range"
min="1"
max="360"
step="1"
aria-labelledby="a standard slider with a label on the top right"
aria-valuemin="1"
aria-valuemax="360"
aria-valuenow="181"
aria-orientation="horizontal"
aria-description="here goes an extensive description text"
value="181"
/>
</div>
<label for="slider10">Degrees</label>
</div>
Standard slider with label left and right top
<div class="a-slider a-slider--labels-on-top">
<label for="slider11">Degrees left</label>
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="absolute"
tooltip-unit="°"
aria-haspopup="false"
>
181°
</span>
<input
tabindex="0"
id="slider11"
type="range"
min="1"
max="360"
step="1"
aria-labelledby="a standard slider with labels on top"
aria-valuemin="1"
aria-valuemax="360"
aria-valuenow="181"
aria-orientation="horizontal"
aria-description="here goes an extensive description text"
value="181"
/>
</div>
<label for="slider11">Degrees</label>
</div>
Standard slider with label left and right top, without tooltip
<div class="a-slider a-slider--labels-on-top">
<label for="slider12">Degrees left</label>
<input
tabindex="0"
id="slider12"
type="range"
min="1"
max="360"
step="1"
aria-labelledby="a standard slider with labels on top without tooltip"
aria-valuemin="1"
aria-valuemax="360"
aria-valuenow="181"
aria-orientation="horizontal"
aria-description="here goes an extensive description text"
value="181"
/>
<label for="slider12">Degrees</label>
</div>
slider vertical
This component is only meant to be used in a full page and won't render / behave correctly here. Please use the button below (Open on blank page) to see the component in action.
<div class="a-slider a-slider--vertical">
<input
tabindex="0"
id="slider13"
type="range"
min="0"
max="100"
step="1"
aria-valuemin="0"
aria-valuemax="100"
aria-orientation="vertical"
aria-label="a vertical slider"
aria-description="here goes an extensive description text"
/>
</div>
slider vertical disabled
This component is only meant to be used in a full page and won't render / behave correctly here. Please use the button below (Open on blank page) to see the component in action.
<div class="a-slider a-slider--vertical">
<input
tabindex="0"
id="slider14"
type="range"
min="0"
max="100"
step="1"
disabled=""
aria-valuemin="0"
aria-valuemax="100"
aria-orientation="vertical"
aria-label="a vertical slider disabled"
aria-description="here goes an extensive description text"
/>
</div>
slider vertical with tooltip
This component is only meant to be used in a full page and won't render / behave correctly here. Please use the button below (Open on blank page) to see the component in action.
<div class="a-slider a-slider--vertical">
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="relative"
aria-haspopup="false"
>
50 %
</span>
<input
tabindex="0"
id="slider15"
type="range"
min="0"
max="100"
step="1"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-orientation="vertical"
aria-label="a vertical slider with tooltip"
aria-description="here goes an extensive description text"
value="50"
/>
</div>
</div>
slider vertical with label
This component is only meant to be used in a full page and won't render / behave correctly here. Please use the button below (Open on blank page) to see the component in action.
<div class="a-slider a-slider--vertical">
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="relative"
aria-haspopup="false"
>
50 %
</span>
<input
tabindex="0"
id="slider16"
type="range"
min="0"
max="100"
step="1"
aria-labelledby="a vertical slider with label"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="50"
aria-orientation="vertical"
aria-description="here goes an extensive description text"
value="50"
/>
<label for="slider16">Label</label>
</div>
</div>
slider vertical with absolute value tooltip
This component is only meant to be used in a full page and won't render / behave correctly here. Please use the button below (Open on blank page) to see the component in action.
<div class="a-slider a-slider--vertical a-slider--unitless">
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="absolute"
aria-haspopup="false"
>
501
</span>
<input
tabindex="0"
id="slider17"
type="range"
min="1"
max="1000"
step="1"
aria-valuemin="1"
aria-valuemax="1000"
aria-valuenow="501"
aria-orientation="vertical"
aria-label="a vertical slider with tooltip with absolute value"
aria-description="here goes an extensive description text"
value="501"
/>
</div>
</div>
slider vertical with absolute value tooltip and unit
This component is only meant to be used in a full page and won't render / behave correctly here. Please use the button below (Open on blank page) to see the component in action.
<div class="a-slider a-slider--vertical">
<div>
<span
class="a-tooltip -floating-shadow-s"
tooltip-type="absolute"
tooltip-unit="°"
aria-haspopup="false"
>
181°
</span>
<input
tabindex="0"
id="slider18"
type="range"
min="1"
max="360"
step="1"
aria-labelledby="a vertical slider with tooltip with absolute value and unit"
aria-valuemin="1"
aria-valuemax="360"
aria-valuenow="181"
aria-orientation="vertical"
aria-description="here goes an extensive description text"
value="181"
/>
<label for="slider18">Degrees</label>
</div>
</div>
additional content
styles SCSS
/* stylelint-disable no-descending-specificity */
/* stylelint-disable a11y/content-property-no-static-value */
@mixin thumb-base {
border-radius: 50%;
height: 1.5rem;
margin-top: -0.71875rem;
position: relative;
width: 1.5rem;
z-index: 999;
}
.a-slider {
--slider-percentage: 50; // This initial value will be overwritten by JS.
height: 3rem;
width: auto;
div {
display: flex;
position: relative;
width: 100%;
flex: 1 1 auto;
margin: 0.5rem 0.75rem;
}
display: flex;
align-items: center;
input {
appearance: none;
background: transparent;
height: 1.5rem;
width: 100%;
-webkit-appearance: none;
outline: 0;
position: relative;
&::before,
&::after {
position: absolute;
content: ' ';
left: 0;
right: 0;
height: 0.125rem;
top: 0.6875rem; // (thumbHeight - trackHeight) / 2 --> (1.5 - 0.125) / 2
}
// Even if the styling is the same, custom colors for Firefox need to be separated from Chrome.
// Styling for the part not in progress of the slider.
// Chrome
&::before {
background: var(--small__enabled__fill__default);
}
// Firefox
&::-moz-range-track {
background: var(--small__enabled__fill__default);
height: 0.13rem;
}
// Styling for the part in progress of the slider.
// Chrome
&::after,
&::-webkit-slider-thumb {
background: var(--major-accent__enabled__fill__default);
width: calc(var(--slider-percentage) * 1%);
}
// Firefox
&::-moz-range-progress,
&::-moz-range-thumb {
background: var(--major-accent__enabled__fill__default);
}
&:hover {
// Chrome
&::after,
&::-webkit-slider-thumb {
background: var(--major-accent__enabled__fill__hovered);
}
// Firefox
&::-moz-range-progress,
&::-moz-range-thumb {
background: var(--major-accent__enabled__fill__hovered);
}
}
&:active {
// Chrome
&::after,
&::-webkit-slider-thumb {
background: var(--major-accent__enabled__fill__pressed);
}
// Firefox
&::-moz-range-progress,
&::-moz-range-thumb {
background: var(--major-accent__enabled__fill__pressed);
}
}
&:disabled {
&::after,
&::-webkit-slider-thumb {
background: var(--major-accent__disabled__fill__default);
}
&::-moz-range-thumb,
&::-moz-range-progress {
background: var(--major-accent__disabled__fill__default);
}
}
// Chrome
&::-webkit-slider-thumb {
@include thumb-base;
-webkit-appearance: none;
}
&::-webkit-slider-runnable-track {
height: 0.125rem;
}
// Firefox
&::-moz-range-thumb {
@include thumb-base;
border: 0;
}
&:focus-visible {
// Chrome
&::-webkit-slider-thumb {
@include focus-outside;
}
// Firefox
&::-moz-range-thumb {
@include focus-outside;
}
}
}
.a-tooltip {
@include floating-outline;
text-align: center;
position: absolute;
bottom: 2.25rem;
left: calc(50% - 1.9375rem);
position: absolute;
text-align: center;
visibility: hidden;
white-space: nowrap;
}
label {
font-size: 1rem;
flex: 0 1 auto;
}
&.a-slider--labels-on-top {
flex-wrap: wrap;
// the labels should not shrink below 50%, but can grow as much as they want
> label {
order: 1;
flex: 1 0 50%;
}
// the div containing the input should not shrink below 100%, and should be
// the third element, visually
// remove the margins around the input so that it aligns with the label's edges
> div,
> input {
order: 3;
flex: 1 0 100%;
margin-left: 0;
margin-right: 0;
}
// the label after the input container should be the second element (visually),
// and the text should right-align
> div + label,
> input + label {
order: 2;
text-align: right;
}
> input {
margin: 0.5rem 0;
}
}
&--vertical {
transform: rotate(270deg);
&:has(label) {
padding-right: 1.75rem;
}
label {
position: absolute;
left: 8.5625rem;
top: -1.75rem;
transform: rotate(90deg);
transform-origin: left bottom;
}
.a-tooltip {
bottom: -3.8rem;
display: flex;
transform: rotate(90deg);
}
}
&--unitless .a-tooltip {
left: calc(50% - 1.625rem);
}
}