Skip to main content

Above is a demonstration of a basic customised cross browser range input slider. I put this together whilst developing UI elements for one of my projects.

Open Demo in New Tab

You can also right-click on the link above and select ‘Save Link As…’ (or similar) to download the entire demo as a single html file.

There are lots of cross browser customised range input sliders out there, however I wanted two bits of key functionality that I didn’t find in any of the examples I came across:

  1. I wanted an additional hit / interactive area around the range slider track, without widening the visual element of the actual range slider track. This would allow me to have a relatively thin visual element for the range slider track whilst also having a more easily clickable/tappable area for making a selection by clicking on the range track (rather than dragging the range thumb). In this version you can make the visual of the slider track and the interactive area different widths, – whatever you want.
  2. I still wanted to include track highlighting to indicate the selected range in the track.

I arrived at a somewhat novel hack / solution that involved adding my own elements behind the actual slider for the slider tracks whilst leaving all the functionality in the native (but restyled) html range input element. Here is another example of this range slider included in the UI for a three.js project.

Here is an example of the HTML:

<div class="range-slider-container">
  <div class="range-track"></div>
  <div id="range-slider-1-track-highlight" class="range-track track-highlight"></div>
  <input type="range" min="0" max="100" value="100" class="slider" id="range_slider_1">
</div>

I then use some JavaScript to resize my custom slider tracks. Here is my complete Javascript code:

let range_slider_1 = document.getElementById("range_slider_1");
    
update_slider()
range_slider_1.addEventListener("input", function (e) {
  update_slider();
});

function update_slider() {
  let slider_value = range_slider_1.value/100;
  let slider_width = range_slider_1.offsetWidth;
  let range_slider_1_value = document.getElementById("range-slider-1-value");
  let range_slider_1_track_highlight = document.getElementById("range-slider-1-track-highlight");
  range_slider_1_track_highlight.style.width = slider_width * slider_value + "px";
  range_slider_1_value.innerHTML = slider_value;
}
window.addEventListener('resize', function(event) {
  update_slider()
}, true);

* Note that I am listening to the window resize to help make the slider responsive.

And here is the CSS:

.range-slider-container {
  position: relative;
  width: 220px;
  margin-top: 10px;
} 
input[type="range"] {
  -webkit-appearance: none;
  height: 10px;
  box-sizing: border-box;
  border:  1px dashed rgba(111,111,111,0.3); /* set opacity to 0 to hide */
  width: 100%;
  background:  0;
  cursor: pointer;
}
.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%; 
  box-sizing: border-box;
  box-shadow: -1px 1px 5px rgba(0,0,0,.4);
  border: 3px solid #ddd;
  background: #04AA6D; /*color*/
}
.slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  box-sizing: border-box;
  box-shadow: -1px 1px 5px rgba(0,0,0,.4); 
  border: 3px solid #ddd;
  background: #04AA6D; /*color*/
}
.range-track {
  width: 100%;
  height: 4px;
  background: #ccc; /*color*/
  position: absolute;
  pointer-events: none;
  top: 10px;
  left:  1px;
  border-radius: 3px;
}
.track-highlight {
  background: #04AA6D; /*color*/
}
#range_slider_1 {
  z-index: 500;
  position: absolute;
  left: 0;
  top: 5px;
}

Otherwise I hope this solution is useful to you and please keep me posted if you find any issues or improvements. 🙂


If you would like to stay in the loop when I publish new content your best bet is to join my mailing list, as I don't tend to post my tutorials and articles to social media. Otherwise you can always follow my work on Youtube, Twitter, Instagram, Reddit, Artstation, LinkedIn, and Behance.

If you liked this resources please consider showing your appreciation and offering your support. It will make my day!

Buy me a coffee

Filed under:
Resources, Three.js, Web Development

Similar Resources:

PWA Template

PWA Template

A minimal template / reference for building Progressive Web Apps.

Blender 3D Art Template File

Blender 3D Art Template File

A Blender template file containing a range of finely tuned lights, cameras, objects, materials, and animation examples, for creating beautiful digital art.

About Me

Hi, I'm Henry Egloff - a multimedia artist, designer, and coder, based in Byron Bay Australia. I create digital art, design and code apps, write articles, and develop tutorials.

I specialise in designing and building dynamic and interactive media with languages like HTML, CSS, PHP, and Javascript, and using tools like Three.js, Blender, Adobe, and Unity.

I love working creatively and helping people learn.

I'm currently available for freelance / contract projects and online tuition roles. Learn more about me or say hello at contact@henryegloff.com.

Henry Egloff
Twitter Twitter 2 Facebook Linked In Instagram Codepen Behance Youtube Opensea Heart Dark Mode Light Mode