Range Slider

v0.1a

Implementing this component

The Markup

				
	<form id="form-range" class="t-neutral">
    <fieldset class="range-slider">
      <label for="input-width" class="range-slider__label">Form range</label>
      <input type="range" name="range" min="0" max="500" step="10" value="250" id="input-width" class="range-slider__input">
    </fieldset>
  </form>
				
			

The CSS: Theming

				
	/* Theming styles */
  .t-neutral .range-slider input[type="range"] {
      background: -webkit-linear-gradient(left, rgba(51,51,51,1) 0%, rgba(51,51,51,1) 100%);
      border-color: #eee;
  }
  .t-neutral .range-slider input[type="text"] {
   background: #fff;
  }
  .t-neutral .range-slider input[type="range"]:focus {
      /* Any styles specific that need to be changed when this is focused due to the initial state */
      border-color: rgba(249, 241, 155, 0.5);
  }

  /* Focus states for all thumbs */
  .t-neutral .range-slider input[type="range"]:focus::-webkit-slider-thumb {
      background-color: rgba(249, 241, 155, 1);
      outline: 2px #686546 thin dotted;
  }
  .t-neutral .range-slider input[type="range"]:focus::-moz-range-thumb {
      background-color: rgba(249, 241, 155, 1);
      outline: 2px #686546 thin dotted;
      -moz-outline-radius:100%;
  }
  .t-neutral .range-slider input[type="range"]:focus::-ms-thumb {
      background-color: rgba(249, 241, 155, 1);
      outline: 2px #686546 thin dotted;
  }
  /* Thumb colors */
  .t-neutral .range-slider input[type="range"]::-ms-thumb {
    background: #fff;
  }
  .t-neutral .range-slider input[type="range"]::-moz-range-thumb {
    background: #fff;
  }
  .t-neutral .range-slider input[type="range"]::-webkit-slider-thumb {
    background-color: #fff;
  }
  /* Theme slider color */
  .t-neutral .range-slider input[type="range"]::-webkit-slider-runnable-track {
    background-color: #444;
  }
  .t-neutral .range-slider input[type="range"]::-moz-range-track {
     background-color: #444;
  }
  .t-neutral .range-slider input[type="range"]::-ms-fill-upper,
  .t-neutral .range-slider input[type="range"]::-ms-fill-lower {
    background-color: #333;
  }
  /* Theme slider focus colors */
  .t-neutral .range-slider input[type="range"]:focus::-ms-fill-upper {
      background-color: #555;
  }
  .t-neutral .range-slider input[type="range"]:focus::-webkit-slider-runnable-track {
      background-color: rgba(249, 241, 155, 0.5);
  }
  .t-neutral .range-slider input[type="range"]:focus::-moz-range-track {
      background-color: rgba(249, 241, 155, 0.5);
  }
  .t-neutral .range-slider input[type="range"]:focus::-ms-fill-lower {
      background-color: #017afd;
  }
				
			

The CSS: Reset

				
/* Resets */
/* Note: this is a fairly optional reset,
you could keep the tooltip */
.form-range input[type="range"]::-ms-tooltip {
    display: none;
}
				
			

The CSS: Component

				
 /* Component */
.range-slider__label {
  font-family: "Helvetica Neue", Helvetica, Verdana, arial, sans-serif;
  display: block;
  margin: 1em 0;
  text-align:left;
}
.range-slider input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  /* This property are needed to allow Android to display the background at all */
  border-radius:10px;
  width: 100%;
  font-size: 1em;
}

.range-slider input[type="range"]:focus {
  outline: dotted thin;
}

.range-slider input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  height: 30px;
  width: 30px;
  border-radius: 100%;
  cursor: pointer;
  margin-top: -6px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
  border: none;
}

.range-slider input[type="range"]::-webkit-slider-runnable-track {
  width: 100%;
  height: 15px;
  cursor: pointer;
  background-color: inherit;
  border-radius: 15px;

}

.range-slider input[type="range"]::-moz-range-thumb {
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
  height: 30px;
  width: 30px;
  border-radius: 100%;
  cursor: pointer;
  border: none;
}

.range-slider input[type="range"]::-moz-range-track {
  width: 100%;
  height: 15px;
  cursor: pointer;
  border-radius: 15px;
}

.range-slider input[type="range"]::-ms-thumb {
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
  height: 30px;
  width: 30px;
  border-radius: 100%;
  cursor: pointer;
  border: none;
  margin: 10px;
}

.range-slider input[type="range"]::-ms-track {
/* IE needs a border hack to make it appear to have the thumb outside of the track */
  cursor: pointer;
  border-top: 16px;
  border-bottom: 17px;
  border-left: 10px;
  border-right: 10px;
  border-style: solid;
  height: 15px;
  background: transparent;
  color: transparent;
}

.range-slider input[type="range"]::-ms-fill-lower,
.range-slider input[type="range"]::-ms-fill-upper {
  border-radius: 15px;
}

/* fallback for IE8/9 when range is a text input */
.range-slider input[type="text"] {
  font-size: 1em;
  padding: 0.5em;
}

				
			

About the component

This is a range slider for inputting number values that don't need the precision of an input type number.

Screen Reader notes

Apple Voiceover

Alerts the label and the input's value as it would the unstyled element.

JAWS

Alerts the label, the input's value, and any changes made to the value as the thumb track on the input move.

NVDA

Alerts the label, the input's value, and any changes made to the value as the thumb track on the input move.

Keyboard control

Just like the native element, the left key lowers the value, the right key increases the value. As the native outline keyboard focus was a bit janky, changing the entire track and thumb on keyboard focus will make it easier to see it has keyboard focus.

High Contrast

Switches contrast easily in high contrast mode.

Inputs

As long as the thumb track is large enough it should be fine for touch and pointers natively.

Cross browser notes

Similar appearance on all modern browsers, IE9 and 8 fall back to an input type text.

Cross device notes

Android 4.12 and older android devices receive a slightly fatter range track.