Sliders
beta

Slider with initial indicator, axis labels, and value

less risk
more risk
less risk
more risk

Slider with initial indicator, axis labels, and moving text value

less risk
more risk
less risk
more risk

Slider with axis

less risk
more risk
less risk
more risk

Standard slider

JavaScript snippet provided for reference only.
(function() {
  // init
  $('.slider').not('pre .slider').each(initSlider);

  // update on input event (webkit,moz) and change events (ie,ms)
  $('.slider').not('pre .slider').on('input change', updateSlider);

  // set initial value as attr, initialize js text and strokes
  function initSlider(index, slider) {
    var $slider = $(slider);
    $slider.attr('initial', $slider.attr('value'));
    // set unique id in order to use output[for] for accessible slider value output
    var id = 'range-slider-' + index;
    $slider.attr('id', id);
    $slider.parents('slider-container').find('.text-value').attr('for', id);
    updateSlider($slider);
    updateTextValueWrapperHeight($slider);
  }

  function updateSlider($slider) {
    // set $slider to event target, or argument, depending on context
    if ($(this).is('input')) $slider = $(this);
    // all feature classes are set on container element
    var $sliderContainer = $slider.parents('.slider-container');
    // initial values necessary for stroke and text updates:
    // initial value on init
    var initial = $slider.attr('initial');
    // step value, necessary to calculate offset
    var step = parseFloat($slider.attr('step'));
    // current value for text purposes
    var textVal = $slider.val();
    // current value for positioning
    var val = textVal - step;
    // min value
    var min = $slider.attr('min');
    // max value
    var max = $slider.attr('max');
    // range
    var range = max - min;

    // update slider stroke (used in all varieties)
    updateSliderStroke();

    // update initial stroke
    if ($sliderContainer.hasClass('has-initial-value-stroke')) {
      updateSliderInitialStroke()
    }
    // update text
    if ($sliderContainer.hasClass('has-text-value')) {
      updateSliderText();
    }
    // update text position
    if ($sliderContainer.hasClass('has-moving-text-value')) {
      updateSliderTextPos();
    }

    // show slider position
    function updateSliderStroke() {
      var width = val / range * 100 + '%';
      var $stroke = $slider.siblings('.stroke');
      $stroke.width(width);
    }

    // show initial selection
    function updateSliderInitialStroke() {
      var $strokeLower = $slider.siblings('.stroke-initial.lower');
      var $strokeUpper = $slider.siblings('.stroke-initial.upper');
      $strokeLower.show().width(initial * 1000 + '%');
      $strokeUpper.show().css('left', initial * 1000 + '%');
      if (val > initial) {
        $strokeUpper.width(Math.abs(initial - val) * 1000 + '%');
      } else {
        $strokeUpper.width(0);
      }
    }

    // update text to match slider value
    function updateSliderText() {
      var val = $slider.val();
      // decimal to %
      var textValue = (val * 100).toFixed(2) + '%';
      $slider.parents('.slider-container').find('.text-value').show().text(textValue);
    }

    // update text position to follow slider thumb
    function updateSliderTextPos() {;
      var left = (val / range * 100);
      // update text pos
      var textWidth = $slider
        .parents('.slider-container')
        .find('.text-value').width();
      var calc = 'calc(' + left + '% - ' + textWidth / 2 + 'px)';
      $slider
        .parents('.slider-container')
        .find(".text-value")
        .css({
          'left': calc,
          'right': 'auto'
        })
    }
  }
  // update .text-value-wrapper min-height to accomodate font-size of .text-value
  function updateTextValueWrapperHeight($slider) {
    var textValueHeight = $slider.parents('.slider-container').find('.text-value').outerHeight();
    $slider.parents('.slider-container').find('.text-value-wrapper').css('min-height', textValueHeight);
  }
})();