Skip to content

Slider13.10.5

The _Slider_ input (referred to as _range_ input as well) allows users to enter a value within constrained range.


$ npm i @if-design-system/slider@13.10.5

0
100
Edit this section

Usage

Principles

Sliders can have 2 states:

  • initialized (where a slider value is already set, and it shows progress);
  • uninitialized (slider is at its default state, with thumb resting at the middle, no progress is shown);

Initialized

0
100

Uninitialized

0
100
Edit this section

Accessibility

Slider or input[type=range], just like any other input element, requires an associated label

<div class="if slider-container">

    <label for="slider-id" class="if slider-data">
      <span>Slider Data</span>
    </label>
    
    <input
        type="range"
        role="slider"
        id="slider-id"
        class="if slider has-progress"
        aria-valuemin="0"
        aria-valuemax="100"
        aria-valuenow="50"
        max="100"
        min="0"
        step="1"
        value="50"
        style="--min: 0; --max: 100; --val: 50;">
    
    <div class="if slider-values">
        <div class="if min">0</div>
        <div class="if max">100</div>
    </div>

</div>

For screen readers to pick up the change in the value of Slider, it is necessary to update the aria-valuenow along with value attribute.

const rangeInput = document.querySelector('input[type=range].slider');
rangeInput.addEventListener('input', (event) => {
    const currentValue = event.target.value;
    rangeInput.style.setProperty('--val', currentValue);
    rangeInput.setAttribute('value', currentValue);
    rangeInput.setAttribute('aria-valuenow', currentValue);
}, false);

If the value of aria-valuenow is not user-friendly, e.g., the day of the week is represented by a number, the aria-valuetext attribute should be present and set to a string that makes the slider value understandable, e.g., "Monday".

const weekDayMap = {1: 'Monday', 2: 'Tuesday', 3: 'Wednesday', /* ... */ };
const rangeInput = document.querySelector('input[type=range].slider');
rangeInput.addEventListener('input', (event) => {
    const currentValue = event.target.value;
    // ...
    rangeInput.setAttribute('aria-valuetext', weekDayMap[currentValue])
}, false);
Edit this section

Anatomy

0
100
  1. Label element
  2. Slider without initial value set
  3. Min value label
  4. Max value label
Edit this section

Specs

0
100
Sizing

Slider data label has 1rem (16px) bottom margin.

Height of slider is 2rem (32px).

Descriptive slider value labels have aline height of 1.75rem (28px) and are positioned right under the slider element.

Edit this section

Implementation

Below is the markup for Slider element.

  • Please note the aria-valuenow and value attributes and --val css variable - these values must be updated with javascript on input change (example code provided below).
  • If there is no initial value set on the Slider leave aria-valuenow and value attributes without any value set and do not add the --val css variable in style attribute.

<div class="if">
    <div class="if block">
        <div class="if container">
            <div class="if slider-container">
                <label for="slider-id" class="if slider-data">
                    <span>Slider Data</span>
                </label> 
                <input
                    type="range"
                    role="slider"
                    id="slider-id"
                    class="if slider"
                    aria-valuemin="0"
                    aria-valuemax="100"
                    aria-valuenow=""
                    max="100"
                    min="0"
                    step="1"
                    value=""
                    style="--min: 0; --max: 100;">
                
                <div class="if slider-values">
                    <div class="if min">0</div>
                    <div class="if max">100</div>
                </div>
            </div>
        </div>
    </div>
</div>
This is an example slider implementation in JavaScript
  window.onload = function() {
    // class name used for progress bar display
    // it is crucial to not change it
    const PROGRESS_CLASSNAME = 'has-progress';
    // get every slider element
    const rangeInputList = document.querySelectorAll('input[type=range].slider');

    // initialize every slider element
    rangeInputList.forEach(rangeInput => {
      const isValDefined = rangeInput.style.getPropertyValue('--val').length > 0;
      let hasProgressClass = rangeInput.classList.value.indexOf(PROGRESS_CLASSNAME) > -1;

      // if there is a value already provided and no progress element in DOM,
      // it means that progress should be displayed
      if (isValDefined && !hasProgressClass) {
        rangeInput.classList.add(PROGRESS_CLASSNAME);
      }

      // add "input" event listener to the slider
      rangeInput.addEventListener(
        'input',
        event => {
          const currentValue = event.target.value;
          // update the '--val' css variable
          // it is used in progress calculation
          rangeInput.style.setProperty('--val', currentValue);
          // set `value` and 'aria-valuenow' attributes according to 
          // current position of slider thumb 
          rangeInput.setAttribute('value', currentValue);
          rangeInput.setAttribute('aria-valuenow', currentValue);
          
          // if at this point there is no progress bar visible
          // add it to slider, since user has moved the thumb
          if (!hasProgressClass) {
            hasProgressClass = true;
            rangeInput.classList.add(PROGRESS_CLASSNAME);
          }
        },
        false
      );
    });
  };
Edit this section

Contact us