Input type range

facebook-svg gplus-svg twitter-svg

Dar estilo a los "sliders" ( <input type="range"> ) es bastante difícil, pero no imposible.

Las reglas de estilo a utilizar son:


input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
}

input[type='range']:focus {
  outline: none;
}

input[type=range]::-webkit-slider-thumb {
  margin-top: -9px;
}

input[type=range]::-moz-range-thumb {}

input[type=range]::-ms-thumb {}

input[type=range]::-webkit-slider-runnable-track {}

input[type=range]:focus::-webkit-slider-runnable-track {
  outline: none;
}

input[type=range]::-moz-range-track {}

input[type=range]::-ms-track {}

input[type=range]::-ms-fill-lower {}

input[type=range]::-ms-fill-upper {}

La explicación del código

Primero en los navegadores de tipo webkit ( Google Chrome, Opera, etc ) tenemos que anular los estilos con los cuales las barras de desplazamiento vienen de fabrica. Para esto utilizamos -webkit-appearance: none;

input[type='range'], input[type='range']::-webkit-slider-runnable-track, input[type='range']::-webkit-slider-thumb {-webkit-appearance: none;}
THUMB

Para dar estilo al "thumb" ( el botón o el control de la barra de desplazamiento ) utilizamos estas reglas de estilo:
( En los navegadores de tipo webkit necesitamos dar un margin-top negativo, por ejemplo margin-top: -9px. )

input[type=range]::-webkit-slider-thumb{margin-top: -9px;}
input[type=range]::-moz-range-thumb{ }
input[type=range]::-ms-thumb{ }
TRACK

Para dar estilo al "track" o la barra de desplazamiento utilizamos estas otras reglas de estilo:

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

En los navegadores de tipo webkit los input enfocados ( on focus ) tienen una sombra azulada. Para que esta sombra no aparezca, utilizamos estas reglas CSS:

input[type='range']:focus {outline : none;}
input[type=range]:focus::-webkit-slider-runnable-track{outline: none;}

Para dar estilos diferentes a las varias partes del "track" el Internet Explorer nos lo pone muy fácil:
Para la parte inferior ( lower ), antes del botón:

input[type=range]::-ms-fill-lower{}

Para la parte superior ( upper ) después del botón:

input[type=range]::-ms-fill-upper{}

Veamos un ejemplo

No queremos crear algo muy complicado, solo queremos demonstrar cómo utilizar todas estas reglas.


* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.inputDiv {
  width: 250px;
  margin: 100px auto;
  position: relative;
}

input[type='range'] {
  display: block;
  width: 250px;
}

input[type='range']:focus {
  outline: none;
}

input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
}

input[type=range]::-webkit-slider-thumb {
  background-color: #777;
  width: 20px;
  height: 20px;
  border: 3px solid #333;
  border-radius: 50%;
  margin-top: -9px;
}

input[type=range]::-moz-range-thumb {
  background-color: #777;
  width: 15px;
  height: 15px;
  border: 3px solid #333;
  border-radius: 50%;
}

input[type=range]::-ms-thumb {
  background-color: #777;
  width: 20px;
  height: 20px;
  border: 3px solid #333;
  border-radius: 50%;
}

input[type=range]::-webkit-slider-runnable-track {
  background-color: #777;
  height: 3px;
}

input[type=range]:focus::-webkit-slider-runnable-track {
  outline: none;
}

input[type=range]::-moz-range-track {
  background-color: #777;
  height: 3px;
}

input[type=range]::-ms-track {
  background-color: #777;
  height: 3px;
}

input[type=range]::-ms-fill-lower {
  background-color: HotPink
}

input[type=range]::-ms-fill-upper {
  background-color: black;
} 

En el HTML utilizamos autocomplete="off" para que Firefox no "recuerde" el valor del input al actualizar la página ( on refresh )


Añadir una "etiqueta"

Esto está muy bien, pero podemos mejorar mucho la usabilidad añadiendo una "etiqueta" donde poner el valor del <input>.


Para esto en el JavaScript utilizamos el evento "input". Cada vez que el valor del <input> cambia el JavaScript leerá  el nuevo valor y lo mostrará en pantalla como el HTML interno ( innerHTML )  de la etiqueta.


var elInput = document.querySelector('#input');
if (elInput) {
  var etiqueta = document.querySelector('#etiqueta');
  if (etiqueta) {
    etiqueta.innerHTML = elInput.value;

    elInput.addEventListener('input', function() {
      etiqueta.innerHTML = elInput.value;
    }, false);
  }
}

También podemos dar formato a la etiqueta, y hacer que se desplace a lo largo del "track" junto con el control o el botón de la barra de desplazamiento ( thumb ).
Esto es bastante fácil, ya que podemos calcular la posición de la etiqueta en función del valor del <input>


.etiqueta {
  width: 30px;
  height: 26px;
  position: absolute;
  z-index: 9;
  background-color: HotPink;
  color: white;
  font-size: 12px;
  text-align: center;
  padding-top: 7px;
  top: -45px;
}

.etiqueta:after {
  content: '';
  display: block;
  width: 10px;
  height: 10px;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
  z-index: 8;
  background-color: HotPink;
  position: relative;
  left: 9px;
}
 

Calculamos la anchura del <input>.

var elInput = document.querySelector("input[type='range']");
var w = parseInt(window.getComputedStyle(elInput, null).getPropertyValue("width"));

Calculamos un cociente pxls que representa el valor en pixeles de 1 punto en la barra de desplazamiento.

var pxls = w/100;

Ahora es muy fácil calcular la posición de la etiqueta en cada momento:

etiqueta.style.left =  ((elInput.value * pxls) - 15)+"px";

Donde 15 representa la mitad de la anchura de la etiqueta.



// EL INPUT 
var elInput3 = document.querySelector('#input3');
if (elInput3) {
  var w = parseInt(window.getComputedStyle(elInput3, null).getPropertyValue('width'));

  // LA ETIQUETA 
  var etq = document.querySelector('.etiqueta');
  if (etq) {
    // el valor de la etiqueta (el tooltip) 
    etq.innerHTML = elInput3.value;

    // calcula la posición inicial de la etiqueta (el tooltip); 
    var pxls = w / 100;

    etq.style.left = ((elInput3.value * pxls) - 15) + 'px';

    elInput3.addEventListener('input', function() {
      // cambia el valor de la etiqueta (el tooltip) 
      etq.innerHTML = elInput3.value;
      // cambia la posición de la etiqueta (el tooltip) 
      etq.style.left = ((elInput3.value * pxls) - 15) + 'px';

    }, false);
  }
}

Pero que pasa si el valor inicial ( min ) no es 0, y el valor final ( max ) no es 100? Vea un ejemplo

<input type="range" value='45' min="20" max="60"  autocomplete="off">

Además es posible que queramos insertar varias barras de desplazamiento en la misma página. Lea este artículo para ver cómo hacerlo.