Respostas:
Não, a entrada do intervalo HTML5 aceita apenas uma entrada. Eu recomendo que você use algo como o controle deslizante de intervalo da interface do usuário jQuery para essa tarefa.
Eu estive procurando por um controle deslizante duplo leve e livre de dependências por algum tempo (parecia loucura importar jQuery apenas para isso) e não parece haver muitos por aí. Acabei modificando um pouco o código do @Wildhoney e gostei muito.
Chegando tarde, mas noUiSlider evita ter uma dependência jQuery-ui, o que a resposta aceita não. Sua única "ressalva" é que o suporte do IE é para o IE9 e mais recentes, se o IE legado for um obstáculo para você.
Também é gratuito, de código aberto e pode ser usado em projetos comerciais sem restrições.
Instalação: Baixe noUiSlider, extraia o arquivo CSS e JS em algum lugar do sistema de arquivos do seu site e, a seguir, vincule ao CSS do cabeçalho e ao JS do corpo:
<!-- In <head> -->
<link href="nouislider.min.css" rel="stylesheet">
<!-- In <body> -->
<script src="nouislider.min.js"></script>
Exemplo de uso: Cria um controle deslizante que vai de 0 a 100 e começa definido como 20-80.
HTML:
<div id="slider">
</div>
JS:
var slider = document.getElementById('slider');
noUiSlider.create(slider, {
start: [20, 80],
connect: true,
range: {
'min': 0,
'max': 100
}
});
Claro que você pode simplesmente usar dois controles deslizantes sobrepostos um ao outro e adicionar um pouco de javascript (na verdade, não mais do que 5 linhas) para que os seletores não excedam os valores mínimo / máximo (como em @Garys) da solução.
Em anexo, você encontrará um pequeno snippet adaptado de um projeto atual, incluindo alguns estilos CSS3 para mostrar o que você pode fazer (apenas webkit). Também adicionei alguns rótulos para exibir os valores selecionados.
Ele usa JQuery, mas uma versão vanillajs não é mágica.
(function() {
function addSeparator(nStr) {
nStr += '';
var x = nStr.split('.');
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + '.' + '$2');
}
return x1 + x2;
}
function rangeInputChangeEventHandler(e){
var rangeGroup = $(this).attr('name'),
minBtn = $(this).parent().children('.min'),
maxBtn = $(this).parent().children('.max'),
range_min = $(this).parent().children('.range_min'),
range_max = $(this).parent().children('.range_max'),
minVal = parseInt($(minBtn).val()),
maxVal = parseInt($(maxBtn).val()),
origin = $(this).context.className;
if(origin === 'min' && minVal > maxVal-5){
$(minBtn).val(maxVal-5);
}
var minVal = parseInt($(minBtn).val());
$(range_min).html(addSeparator(minVal*1000) + ' €');
if(origin === 'max' && maxVal-5 < minVal){
$(maxBtn).val(5+ minVal);
}
var maxVal = parseInt($(maxBtn).val());
$(range_max).html(addSeparator(maxVal*1000) + ' €');
}
$('input[type="range"]').on( 'input', rangeInputChangeEventHandler);
})();
body{
font-family: sans-serif;
font-size:14px;
}
input[type='range'] {
width: 210px;
height: 30px;
overflow: hidden;
cursor: pointer;
outline: none;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
background: none;
}
input[type='range']::-webkit-slider-runnable-track {
width: 200px;
height: 1px;
background: #003D7C;
}
input[type='range']:nth-child(2)::-webkit-slider-runnable-track{
background: none;
}
input[type='range']::-webkit-slider-thumb {
position: relative;
height: 15px;
width: 15px;
margin-top: -7px;
background: #fff;
border: 1px solid #003D7C;
border-radius: 25px;
z-index: 1;
}
input[type='range']:nth-child(1)::-webkit-slider-thumb{
z-index: 2;
}
.rangeslider{
position: relative;
height: 60px;
width: 210px;
display: inline-block;
margin-top: -5px;
margin-left: 20px;
}
.rangeslider input{
position: absolute;
}
.rangeslider{
position: absolute;
}
.rangeslider span{
position: absolute;
margin-top: 30px;
left: 0;
}
.rangeslider .right{
position: relative;
float: right;
margin-right: -5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="rangeslider">
<input class="min" name="range_1" type="range" min="1" max="100" value="10" />
<input class="max" name="range_1" type="range" min="1" max="100" value="90" />
<span class="range_min light left">10.000 €</span>
<span class="range_max light right">90.000 €</span>
</div>
Na verdade eu usei meu script em html diretamente. Mas em javascript, quando você adiciona um ouvinte de evento de entrada para este evento, ele fornece os dados automaticamente. Você só precisa atribuir o valor de acordo com sua necessidade.
[slider] {
width: 300px;
position: relative;
height: 5px;
margin: 45px 0 10px 0;
}
[slider] > div {
position: absolute;
left: 13px;
right: 15px;
height: 5px;
}
[slider] > div > [inverse-left] {
position: absolute;
left: 0;
height: 5px;
border-radius: 10px;
background-color: #CCC;
margin: 0 7px;
}
[slider] > div > [inverse-right] {
position: absolute;
right: 0;
height: 5px;
border-radius: 10px;
background-color: #CCC;
margin: 0 7px;
}
[slider] > div > [range] {
position: absolute;
left: 0;
height: 5px;
border-radius: 14px;
background-color: #d02128;
}
[slider] > div > [thumb] {
position: absolute;
top: -7px;
z-index: 2;
height: 20px;
width: 20px;
text-align: left;
margin-left: -11px;
cursor: pointer;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4);
background-color: #FFF;
border-radius: 50%;
outline: none;
}
[slider] > input[type=range] {
position: absolute;
pointer-events: none;
-webkit-appearance: none;
z-index: 3;
height: 14px;
top: -2px;
width: 100%;
opacity: 0;
}
div[slider] > input[type=range]:focus::-webkit-slider-runnable-track {
background: transparent;
border: transparent;
}
div[slider] > input[type=range]:focus {
outline: none;
}
div[slider] > input[type=range]::-webkit-slider-thumb {
pointer-events: all;
width: 28px;
height: 28px;
border-radius: 0px;
border: 0 none;
background: red;
-webkit-appearance: none;
}
div[slider] > input[type=range]::-ms-fill-lower {
background: transparent;
border: 0 none;
}
div[slider] > input[type=range]::-ms-fill-upper {
background: transparent;
border: 0 none;
}
div[slider] > input[type=range]::-ms-tooltip {
display: none;
}
[slider] > div > [sign] {
opacity: 0;
position: absolute;
margin-left: -11px;
top: -39px;
z-index:3;
background-color: #d02128;
color: #fff;
width: 28px;
height: 28px;
border-radius: 28px;
-webkit-border-radius: 28px;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
text-align: center;
}
[slider] > div > [sign]:after {
position: absolute;
content: '';
left: 0;
border-radius: 16px;
top: 19px;
border-left: 14px solid transparent;
border-right: 14px solid transparent;
border-top-width: 16px;
border-top-style: solid;
border-top-color: #d02128;
}
[slider] > div > [sign] > span {
font-size: 12px;
font-weight: 700;
line-height: 28px;
}
[slider]:hover > div > [sign] {
opacity: 1;
}
<div slider id="slider-distance">
<div>
<div inverse-left style="width:70%;"></div>
<div inverse-right style="width:70%;"></div>
<div range style="left:0%;right:0%;"></div>
<span thumb style="left:0%;"></span>
<span thumb style="left:100%;"></span>
<div sign style="left:0%;">
<span id="value">0</span>
</div>
<div sign style="left:100%;">
<span id="value">100</span>
</div>
</div>
<input type="range" value="0" max="100" min="0" step="1" oninput="
this.value=Math.min(this.value,this.parentNode.childNodes[5].value-1);
let value = (this.value/parseInt(this.max))*100
var children = this.parentNode.childNodes[1].childNodes;
children[1].style.width=value+'%';
children[5].style.left=value+'%';
children[7].style.left=value+'%';children[11].style.left=value+'%';
children[11].childNodes[1].innerHTML=this.value;" />
<input type="range" value="100" max="100" min="0" step="1" oninput="
this.value=Math.max(this.value,this.parentNode.childNodes[3].value-(-1));
let value = (this.value/parseInt(this.max))*100
var children = this.parentNode.childNodes[1].childNodes;
children[3].style.width=(100-value)+'%';
children[5].style.right=(100-value)+'%';
children[9].style.left=value+'%';children[13].style.left=value+'%';
children[13].childNodes[1].innerHTML=this.value;" />
</div>