Input type range
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.