Range Input Enhancement: CSS/JS Tips

A person coding with futuristic HTML and CSS holographic interfaces

Customizing the HTML range slider involves styling two key pseudo-elements: ::-webkit-slider-thumb for the slider thumb, and ::-webkit-slider-runnable-track for the track the thumb slides on. Here’s how to enhance its functionality and aesthetics. The <input type=”range”> element is a slider interface within HTML forms, enabling value selection through thumb control.

However, the default style of the range slider is simplistic and lacks informative cues, potentially leading to user confusion. Moreover, its visual presentation varies among different web browsers. Enhancements can be made solely with CSS and JavaScript, enriching the user experience without external libraries.  Explore Input Range CSS in-depth in this guide, and gain practical insights into CSS table cell spacing through the related article. 

Adjusting Range Input Color with accent-color Property

Customizing the accent color of the range input is easily achieved without additional HTML or specific selectors. Simply alter the color of the range by defining the accent-color property for the input[type=”range”] selector, as demonstrated below:

input[type="range"] {
  accent-color: coral;
}

Styling the Range Input

The range input widget comprises two distinct components: the thumb and the track. To style each part effectively, use the respective pseudo-class selectors, each accompanied by a vendor suffix for optimal cross-browser support.

Thumb:

input[type="range"]::-webkit-slider-thumb
input[type="range"]::-moz-range-thumb
input[type="range"]::-ms-thumb

Track:

input[type="range"]::-webkit-slider-runnable-track
input[type="range"]::-moz-range-track
input[type="range"]::-ms-track


input[type="range"] {
  -webkit-appearance: none;
  margin-right: 15px;
  width: 200px;
  height: 7px;
  background: rgba(255, 255, 255, 0.6);
  border-radius: 5px;
  background-image: linear-gradient(#ff4500, #ff4500);
  background-size: 70% 100%;
  background-repeat: no-repeat;
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 20px;
  width: 20px;
  border-radius: 50%;
  background: #ff4500;
  cursor: ew-resize;
  box-shadow: 0 0 2px 0 #555;
  transition: background .3s ease-in-out;
}

input[type=range]::-webkit-slider-runnable-track  {
  -webkit-appearance: none;
  box-shadow: none;
  border: none;
  background: transparent;
}

To highlight the selected value, apply a color gradient from the beginning of the track to the thumb using the background-image property with the linear-gradient() value. The background-size property will be utilized to determine the size, which can be dynamically adjusted later with JavaScript.

Two people discuss code on a large monitor with graphics

Strategies for Improved User Interaction

The default range input lacks specificity regarding selected values, posing a challenge for users to discern the current selection. Although visual cues such as hash marks and labels are beneficial, these features are not universally supported.

Nevertheless, there are practical ways to enhance usability through additional HTML and JavaScript:

  • Introduce an output element to showcase the selected value;
  • Synchronize a number input with the range input to provide a numeric representation.

Utilizing Output Element for Range Input Values

Specify the output element to showcase the selected value by adding an id attribute to the output element. Additionally, include an oninput attribute for the range input, featuring a concise function as its value. This function will dynamically update the content of the output element.

<input type="range" min="0" max="100" oninput="rangevalue.value=value"/>
<output id="rangevalue">50</output>

Synchronizing Number Input with Range Input for Enhanced User Control

To enhance user control, consider adding a number input adjacent to the range element. This allows users to both view the selected value and easily modify it using the number input, offering an improved experience, particularly for mobile users.

<input type="range" value="50" min="0" max="100" id="range" oninput="rangevalue.value=value"/>
<input type="number" id="rangevalue" value="50" oninput="range.value=value">

Implementing Dynamic Functionality with JavaScript

Concluding the process requires the incorporation of JavaScript code to ensure seamless functionality. While the oninput attribute is already adept at updating values based on a target element, additional steps are needed to dynamically update the selected area of the range input.

This involves calculating the ratio and applying that value to the input’s background-size property. Keep in mind that the value property of the range input is of string type; if you intend to use it as a numeric value, utilize the valueAsNumber property.

const rangeInputs = document.querySelectorAll('input[type="range"]')
const numberInput = document.querySelector('input[type="number"]')

function handleInputChange(e) {
  let target = e.target
  if (e.target.type !== 'range') {
    target = document.getElementById('range')
  } 
  const min = target.min
  const max = target.max
  const val = target.value
  
  target.style.backgroundSize = (val - min) * 100 / (max - min) + '% 100%'
}

rangeInputs.forEach(input => {
  input.addEventListener('input', handleInputChange)
})

numberInput.addEventListener('input', handleInputChange)
A woman works with code and cloud services on her laptop

Adapting Custom Range Input for RTL Direction

To ensure the functionality of the custom range input solution in right-to-left (RTL) web pages, adjustments are necessary for both CSS and JavaScript.

The preferred method for setting the text direction of a block or an entire page is to employ the dir attribute.

<html dir="rtl">
  ...
</html>

Upon establishing the dir attribute, you can define the following selector for the range input: [dir=”rtl”] input[type=”range”].

To ensure consistent values for the RTL direction, adjustments must be made to the background colors and values. For instance, for the 70% range, the representation would be as follows:

[dir="rtl"] input[type="range"] {
  /* Used to be gradient color, the current progress */
  background: #ff4500;

  /* Used to be background color, the track */
  background-image: linear-gradient(#fff, #fff);

  /* 30% is the difference between the max and the current value (100 - 70) */
  background-size: 30% 100%;
  background-repeat: no-repeat;
}

Concerning the JavaScript aspect, it is essential to incorporate a condition within the change handler function. This condition is necessary to calculate the accurate value, specifically max – current.

function handleInputChange(e) {
  let target = e.target
  if (e.target.type !== 'range') {
    target = document.getElementById('range')
  } 
  const min = target.min
  const max = target.max
  const val = target.value
  let percentage = (val - min) * 100 / (max - min)
  
  // condition to check whether the document has RTL direction
  // you can move it to a variable, if document direction is dynamic
  if (document.documentElement.dir === 'rtl') {
    percentage = (max - val) 
  }
  
  target.style.backgroundSize = percentage + '% 100%'
}

Conclusion

Improving the <input type=”range”> element with CSS and JavaScript ensures consistent appearance and enhances user interaction. By styling pseudo-elements like ::-webkit-slider-thumb and ::-webkit-slider-runnable-track, developers can create a more intuitive slider. Combining JavaScript adds dynamic feedback and advanced behaviors, elevating the range input as a notable feature in web design. These enhancements are easy to implement, providing a significant usability and aesthetic boost to web form elements.