Home > Blockchain >  Is it possible to style input type=range with just a left and right color and no thumb?
Is it possible to style input type=range with just a left and right color and no thumb?

Time:07-03

An <input type="range"> looks like this on Chrome(103)/MacOS

enter image description here

And this in Firefox(101)

enter image description here

Is there a CSS only way to get it to look like this?

enter image description here

It seems so close, just

  1. Hide the thumb (easy)
  2. Set the border-radius to none (easy)
  3. Set the border to none (easy)
  4. Set a size (easy)
  5. Set the color left of the track different than the right (???)

But I've had no luck

input[type="range"] {
  -webkit-appearance: none;
  width: 200px;
  height: 20px;
  border-radius: none;
  background-color: blue;
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  cursor: ew-resize;
}
<input type="range">

In particular step 5. Is there a way to set left and right colors of the track? Ideally cross browser?

I was trying to think if there was away to use calc and a ::before pseudo element or some recently introduced CSS features like css container queries but nothing came to mind.

PS: I know it's relatively easy to do this in JavaScript by coding my own slider using divs or other elements but I'd love to do it CSS only.

CodePudding user response:

Here is a working example.

function sliderValueChange(e) {
  console.log(e.value);
}
:root {
  --slider-width: 300px;
  --slider-height: 20px;
}

input[type='range'] {
  cursor: ew-resize;
  overflow: hidden;
}

@media screen and (-webkit-min-device-pixel-ratio:0) {
  input[type='range'] {
    width: var(--slider-width);
    -webkit-appearance: none;
    background-color: #353535;
  }
  input[type='range']::-webkit-slider-runnable-track {
    height: var(--slider-height);
    -webkit-appearance: none;
    color: #13bba4;
    margin-top: -1px;
  }
  input[type='range']::-webkit-slider-thumb {
    width: 0px;
    -webkit-appearance: none;
    height: var(--slider-height);
    box-shadow: calc(-1 * var(--slider-width)) 0 0 var(--slider-width) #43e5f7;
  }
}

/* FF */
input[type="range"]::-moz-range-progress {
  background-color: #43e5f7; 
}
input[type="range"]::-moz-range-thumb {
  height: var(--slider-height);
  width: 0;
  border: none;
  box-shadow: calc(-1 * var(--slider-width)) 0 0 var(--slider-width) #43e5f7;
  box-sizing: border-box;
}

/* IE */
input[type="range"]::-ms-fill-lower {
  background-color: #43e5f7; 
}
input[type="range"]::-ms-fill-upper {  
  background-color: #13bba4;
}
<input type="range" onchange="sliderValueChange(this)">

CodePudding user response:

Here you go a CodePen by Noah Blon. A cross-browser range input slider. A box-shadow on the pseudo-thumb element creates a solid color fill effect¹. The ::-webkit-slider-thumb is width: 0 and border: 0 makes it invisible yet it's functionality as a handle remains because it's height: 40px.

¹Also see this article

body {
  height: 100vh;
  margin: 0;
  display: flex;
}

input[type="range"] {
  margin: auto;
  -webkit-appearance: none;
  position: relative;
  overflow: hidden;
  height: 40px;
  width: 200px;
  cursor: pointer;
  border-radius: 0;
}

::-webkit-slider-runnable-track {
  background: #ddd;
}


/*
 * 1. Set to 0 width and remove border for a slider without a thumb
 * 2. Shadow is negative the full width of the input and has a spread 
 *    of the width of the input.
 */

::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 0px;
  /* 1 */
  height: 40px;
  background: #fff;
  box-shadow: -200px 0 0 200px dodgerblue;
  /* 2 */
  border: 0;
  /* 1 */
}

::-moz-range-track {
  height: 40px;
  background: #ddd;
}

::-moz-range-thumb {
  background: #fff;
  height: 40px;
  width: 20px;
  border: 3px solid #999;
  border-radius: 0 !important;
  box-shadow: -200px 0 0 200px dodgerblue;
  box-sizing: border-box;
}
<input type='range'>

  • Related