¿Cómo diseñar la entrada del rango HTML5 para tener un color diferente antes y después del control deslizante?

93

ingrese la descripción de la imagen aquí

Quiero que el lado izquierdo sea verde y el lado derecho gris. Como se muestra arriba sería PERFECTO. Preferiblemente una solución CSS pura (solo hay que preocuparse por WebKit).

¿Es posible tal cosa?

Shamoon
fuente
Probablemente, ¿qué has probado? Publique su código aquí.
j08691

Respuestas:

118

Solución CSS pura :

  • Chrome: oculte el desbordamiento input[range]y llene todo el espacio que queda al pulgar con color de sombra.
  • IE: no es necesario reinventar la rueda:::-ms-fill-lower
  • Firefox no necesita reinventar la rueda:::-moz-range-progress

/*Chrome*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
    input[type='range'] {
      overflow: hidden;
      width: 80px;
      -webkit-appearance: none;
      background-color: #9a905d;
    }
    
    input[type='range']::-webkit-slider-runnable-track {
      height: 10px;
      -webkit-appearance: none;
      color: #13bba4;
      margin-top: -1px;
    }
    
    input[type='range']::-webkit-slider-thumb {
      width: 10px;
      -webkit-appearance: none;
      height: 10px;
      cursor: ew-resize;
      background: #434343;
      box-shadow: -80px 0 0 80px #43e5f7;
    }

}
/** FF*/
input[type="range"]::-moz-range-progress {
  background-color: #43e5f7; 
}
input[type="range"]::-moz-range-track {  
  background-color: #9a905d;
}
/* IE*/
input[type="range"]::-ms-fill-lower {
  background-color: #43e5f7; 
}
input[type="range"]::-ms-fill-upper {  
  background-color: #9a905d;
}
<input type="range"/>

deathangel908
fuente
1
Hola deathangel908, buena solución. Solo mejoraría la parte de la sombra del cuadro: box-shadow: -80px 0 0px 80px # 43e5f7;
Filip Witkowski
32
El problema con esto en cromo es si desea que el pulgar sea más grande que la pista, entonces la sombra del cuadro se superpone a la pista con la altura del pulgar. ¿Hay alguna forma de confinar la sombra de caja dentro de la pista?
mharris7190
1
Esto no funciona para entradas con anchos basados ​​en porcentajes. ¿Alguien tiene una solución para eso?
Remi Sture
2
Puede encontrar una versión funcional de CSS / JS aquí: jsfiddle.net/remisture/esyvws3d
Remi Sture
3
@tenwest Vaya, eso es horrible. ¡Gracias por la actualización!
CodeF0x
50

Si bien la respuesta aceptada es buena en teoría, ignora el hecho de que el pulgar no puede ser más grande que el tamaño de la pista sin ser cortado por overflow: hidden. Vea este ejemplo de cómo manejar esto con solo un poquito de JS.

// .chrome styling Vanilla JS

document.getElementById("myinput").oninput = function() {
  this.style.background = 'linear-gradient(to right, #82CFD0 0%, #82CFD0 ' + this.value + '%, #fff ' + this.value + '%, white 100%)'
};
#myinput {
  background: linear-gradient(to right, #82CFD0 0%, #82CFD0 50%, #fff 50%, #fff 100%);
  border: solid 1px #82CFD0;
  border-radius: 8px;
  height: 7px;
  width: 356px;
  outline: none;
  transition: background 450ms ease-in;
  -webkit-appearance: none;
}
<div class="chrome">
  <input id="myinput" type="range" value="50" />
</div>

dargue3
fuente
¿Me pueden sugerir cuando agregué max = 5 en HTML y luego el color no se llena correctamente?
Husna
@Husna He extendido esta respuesta para manejar también los atributos min max, espero que ayude.
htmn
1
@Husna Tienes que calcular el% como una diferencia entre tu valor máximo y mínimo. Por ejemplo, si tiene min: 0 y max: 10, debe usar, en JS :,+ this.value / (10-0)*100 +'%, #fff
Rosario Russo
4
@Rosario Russo Solo necesitas repasar this.value en el JS con(this.value-this.min)/(this.max-this.min)*100
Silvan
29

Sí, es posible. Aunque no lo recomendaría porqueinput range no es realmente compatible con todos los navegadores porque es un elemento nuevo agregado en HTML5 y HTML5 es solo un borrador (y lo será por mucho tiempo), por lo que ir tan lejos como para diseñarlo quizás no sea el mejor. elección.

Además, también necesitará un poco de JavaScript. Me tomé la libertad de usar la biblioteca jQuery para esto, por motivos de simplicidad.

Aquí tienes: http://jsfiddle.net/JnrvG/1/ .

federico-t
fuente
8
Esa no era la pregunta, qué necesito para hacerlo con css, debe haber una forma solo con css.
Ipad
10
Puede hacer que funcione en Chrome sin JS ( jsfiddle.net/1xg1j3tw ). Para IE10 + puede usar los pseudo elementos -ms-fill-lower y -ms-fill-upper.
Ales
1
@Ales Deberías poner eso en una respuesta adicional.
Luca Steeb
4
Cambie .change(a on('input', func..para que el fondo cambie cuando el usuario mueva el pulgar, no solo el mouse hacia arriba.
Yami Odymel
10

Una pequeña actualización de este:

si usa lo siguiente, se actualizará sobre la marcha en lugar de soltar el mouse.

"cambiar mousemove", función "

<script>
$('input[type="range"]').on("change mousemove", function () {
    var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));

    $(this).css('background-image',
                '-webkit-gradient(linear, left top, right top, '
                + 'color-stop(' + val + ', #2f466b), '
                + 'color-stop(' + val + ', #d3d3db)'
                + ')'
                );
});</script>
James Parker
fuente
7

Sobre la base de la respuesta de @ dargue3 , si desea que el pulgar sea más grande que la pista, desea aprovechar al máximo el <input type="range" />elemento e ir a otro navegador, necesita algunas líneas adicionales de JS y CSS.

En Chrome / Mozilla puede utilizar la linear-gradienttécnica, pero hay que ajustar la relación basada en el min, max, valueatributos como se ha mencionado aquí por @Attila O. . Debe asegurarse de no aplicar esto en Edge, de lo contrario, no se muestra el pulgar. @Geoffrey Lalloué explica esto con más detalle aquí .

Otra cosa que vale la pena mencionar es que debe ajustar rangeEl.style.height = "20px";en IE / Older. En pocas palabras, esto se debe a que en este caso "la altura no se aplica a la pista, sino a toda la entrada, incluido el pulgar". violín

/**
 * Sniffs for Older Edge or IE,
 * more info here:
 * https://stackoverflow.com/q/31721250/3528132
 */
function isOlderEdgeOrIE() {
  return (
    window.navigator.userAgent.indexOf("MSIE ") > -1 ||
    !!navigator.userAgent.match(/Trident.*rv\:11\./) ||
    window.navigator.userAgent.indexOf("Edge") > -1
  );
}

function valueTotalRatio(value, min, max) {
  return ((value - min) / (max - min)).toFixed(2);
}

function getLinearGradientCSS(ratio, leftColor, rightColor) {
  return [
    '-webkit-gradient(',
    'linear, ',
    'left top, ',
    'right top, ',
    'color-stop(' + ratio + ', ' + leftColor + '), ',
    'color-stop(' + ratio + ', ' + rightColor + ')',
    ')'
  ].join('');
}

function updateRangeEl(rangeEl) {
  var ratio = valueTotalRatio(rangeEl.value, rangeEl.min, rangeEl.max);

  rangeEl.style.backgroundImage = getLinearGradientCSS(ratio, '#919e4b', '#c5c5c5');
}

function initRangeEl() {
  var rangeEl = document.querySelector('input[type=range]');
  var textEl = document.querySelector('input[type=text]');

  /**
   * IE/Older Edge FIX
   * On IE/Older Edge the height of the <input type="range" />
   * is the whole element as oposed to Chrome/Moz
   * where the height is applied to the track.
   *
   */
  if (isOlderEdgeOrIE()) {
    rangeEl.style.height = "20px";
    // IE 11/10 fires change instead of input
    // https://stackoverflow.com/a/50887531/3528132
    rangeEl.addEventListener("change", function(e) {
      textEl.value = e.target.value;
    });
    rangeEl.addEventListener("input", function(e) {
      textEl.value = e.target.value;
    });
  } else {
    updateRangeEl(rangeEl);
    rangeEl.addEventListener("input", function(e) {
      updateRangeEl(e.target);
      textEl.value = e.target.value;
    });
  }
}

initRangeEl();
input[type="range"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  width: 300px;
  height: 5px;
  padding: 0;
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}


/*Chrome thumb*/

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  -moz-appearance: none;
  -webkit-border-radius: 5px;
  /*16x16px adjusted to be same as 14x14px on moz*/
  height: 16px;
  width: 16px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*Mozilla thumb*/

input[type="range"]::-moz-range-thumb {
  -webkit-appearance: none;
  -moz-appearance: none;
  -moz-border-radius: 5px;
  height: 14px;
  width: 14px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*IE & Edge input*/

input[type=range]::-ms-track {
  width: 300px;
  height: 6px;
  /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
  background: transparent;
  /*leave room for the larger thumb to overflow with a transparent border */
  border-color: transparent;
  border-width: 2px 0;
  /*remove default tick marks*/
  color: transparent;
}


/*IE & Edge thumb*/

input[type=range]::-ms-thumb {
  height: 14px;
  width: 14px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*IE & Edge left side*/

input[type=range]::-ms-fill-lower {
  background: #919e4b;
  border-radius: 2px;
}


/*IE & Edge right side*/

input[type=range]::-ms-fill-upper {
  background: #c5c5c5;
  border-radius: 2px;
}


/*IE disable tooltip*/

input[type=range]::-ms-tooltip {
  display: none;
}

input[type="text"] {
  border: none;
}
<input type="range" value="80" min="10" max="100" step="1" />
<input type="text" value="80" size="3" />

htmn
fuente
5

La solución aceptada anteriormente ya no funciona .

Terminé codificando una función simple que envuelve el rangeen un contenedor con estilo agregando la barra que se necesita antes del cursor. Escribí este ejemplo donde es fácil ver los dos colores 'azul' y 'naranja' establecidos en el CSS, por lo que se pueden modificar rápidamente.

fedeghe
fuente
1

Si usa la primera respuesta , hay un problema con el pulgar. En cromo si quieres que el pulgar sea ​​más grande que la pista , la sombra del cuadro se superpone a la pista con la altura del pulgar.

Simplemente resuma todas estas respuestas y escribió un control deslizante que funciona normalmente con un pulgar deslizante más grande: jsfiddle

const slider = document.getElementById("myinput")
const min = slider.min
const max = slider.max
const value = slider.value

slider.style.background = `linear-gradient(to right, red 0%, red ${(value-min)/(max-min)*100}%, #DEE2E6 ${(value-min)/(max-min)*100}%, #DEE2E6 100%)`

slider.oninput = function() {
  this.style.background = `linear-gradient(to right, red 0%, red ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 100%)`
};
#myinput {
  border-radius: 8px;
  height: 4px;
  width: 150px;
  outline: none;
  -webkit-appearance: none;
}

input[type='range']::-webkit-slider-thumb {
  width: 6px;
  -webkit-appearance: none;
  height: 12px;
  background: black;
  border-radius: 2px;
}
<div class="chrome">
  <input id="myinput" type="range" min="0" value="25" max="200" />
</div>

abdigali
fuente
0

Ahora es compatible con pseudo elementos en cada uno de WebKit, Firefox e IE. Pero, por supuesto, es diferente en cada uno. : (

Vea las respuestas de esta pregunta y / o busque un CodePen titulado prettify <input type=range> #101para algunas soluciones.

Wilson F
fuente
-5
input type="range" min="0" max="50" value="0"  style="margin-left: 6%;width: 88%;background-color: whitesmoke;"

el código anterior cambia el estilo de entrada del rango .....

Krish
fuente
Funciona en FireFox 57 pero no en Opera 49 ni Safari 11; lo que es peor, nada admite el color de primer plano.
Devon