I have a range input which is having circle shaped handler. I used css to make the handler look like circle. Now that Im trying to find a way to show the value selected inside that circle. But I didn't find any way to do that even after long time. So here I am. Is there any way to do the same ? and one more thing I need to fill the colors on the left and right side of the handler based on the value selected. Can you please suggest how do i do it ? Any help would be appreciated.
Here is the code I used
<input type="range" min="0" max="10"/>
input[type=range]{
-webkit-appearance: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 5px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: 1px solid #e95e57;
height: 32px;
width: 32px;
border-radius: 50%;
background: white;
margin-top: -14px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #ccc;
}
I have a range input which is having circle shaped handler. I used css to make the handler look like circle. Now that Im trying to find a way to show the value selected inside that circle. But I didn't find any way to do that even after long time. So here I am. Is there any way to do the same ? and one more thing I need to fill the colors on the left and right side of the handler based on the value selected. Can you please suggest how do i do it ? Any help would be appreciated.
Here is the code I used
<input type="range" min="0" max="10"/>
input[type=range]{
-webkit-appearance: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 5px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: 1px solid #e95e57;
height: 32px;
width: 32px;
border-radius: 50%;
background: white;
margin-top: -14px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #ccc;
}
Share
Improve this question
asked Nov 4, 2014 at 13:23
KarthickNKarthickN
3351 gold badge7 silver badges21 bronze badges
5
- I can get you part of the way there by suggesting that you add a bit of JS to create an event listener for the input and then apply the value to another element that would have to be manipulated via CSS to appear inside the circle. – DevlshOne Commented Nov 4, 2014 at 13:42
- In that case I ll need to move that input along with the handler right ? Is there any way to do that ? – KarthickN Commented Nov 4, 2014 at 13:59
- I wish I could answer that but I just don't know if the slider itself can be tracked as far as a X,Y location is concerned. – DevlshOne Commented Nov 4, 2014 at 14:05
- Could you please tell more about how you want which colors to be filled? – Markai Commented Nov 4, 2014 at 14:17
- There are 4 slider each will have different colors to be filled. I got it. Thank yo so much for ur help :) – KarthickN Commented Nov 5, 2014 at 6:26
3 Answers
Reset to default 2Here is an answer that covers both aspects mentioned. You can also have multiple range inputs on the same page and all will work individually.
Note: I did use a couple of lines of Markai's code. Thanks to him.
HTML
<div class="range-wrapper"> <input type="range" min="0" max="10" id="myRange"/> <div class="text">1</div> </div> <div class="range-wrapper"> <input type="range" min="0" max="10" id="mySecondRange"/> <div class="text">1</div> </div>
jQuery
$(document).ready(function(){ updateRangeValue($('input[type=range]')); $('input[type=range]').on('input change',function(){ var input = $(this); updateRangeValue(input); }); }); function getRangeGradient(color1,color2,value,maximum){ var gradient = "linear-gradient(to right, "; var breakPoint = (value/maximum)*100; var attrValue = gradient + color1 + " 0%, " + color1 + " " + breakPoint + "%, " + color2 + " " + breakPoint + "%, " + color2 + " 100%)"; return attrValue; } function updateRangeValue(input){ var selectedColor = "#428bca"; var nonSelectedColor = "#ddd"; var value = input.val(); var maximum = input.attr('max'); var inputWidth = input.width(); var background = getRangeGradient(selectedColor, nonSelectedColor, value, maximum); var offLeft = Math.floor((value / maximum) * inputWidth - (((value / maximum) * inputWidth - inputWidth/2) / 100) * 24); var offLeftAbs = value == maximum ? input.offset().left - 15 + offLeft : input.offset().left - 10 + offLeft; input.next('.text').css({'left': offLeftAbs +'px'}); input.next('.text').html(value); input.css('background', background); }
CSS
.range-wrapper { overflow: hidden; padding: 5px 0px; } .range-wrapper > div { position: relative; top: -15px; width: 5px; } .range-wrapper > .text { pointer-events: none; } input[type=range]{ -webkit-appearance: none; background: linear-gradient(to right, #428bca 0%, #428bca 50%, #ddd 50%, #ddd 100%); } input[type=range]::-webkit-slider-runnable-track { width: 300px; height: 5px; border: none; border-radius: 3px; } input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; border: 1px solid #e95e57; height: 32px; width: 32px; border-radius: 50%; background: white; margin-top: -14px; cursor: pointer; } input[type=range]:focus { outline: none; background: linear-gradient(to right, #428bca 0%, #428bca 50%, #ddd 50%, #ddd 100%); }
Here is the jsFiddle link.
Hope this helps.
I can suggest not very cross-browser solution using canvas as background:
function renderValue(value) {
var ctx = document.getCSSCanvasContext('2d', 'value', 32, 32);
ctx.fillStyle = '#FFF';
ctx.fillRect(0, 0, 32, 32);
ctx.font = 'bold 18px Arial';
ctx.fillStyle = '#888';
ctx.textAlign = 'center';
ctx.fillText(value, 15, 21);
}
var input = document.querySelector('input')
input.oninput = function() {
renderValue(this.value);
}
renderValue(input.value);
input[type=range] {
-webkit-appearance: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 5px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: 1px solid #e95e57;
height: 32px;
width: 32px;
border-radius: 50%;
margin-top: -14px;
background: -webkit-canvas(value) no-repeat 0 0;
}
input[type=range]:focus {
outline: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #ccc;
}
div.test {
background: -webkit-canvas(clouds) no-repeat 0 0;
height: 100px;
width: 100px;
border: 1px red solid;
}
canvas {
border: 1px red solid;
}
<input type="range" min="0" max="10" data-value="3" />
I have kind of a solution, that should work cross browser, but it is pretty ugly and has the problem, that there is a text over the button which makes it only dragable on the sides (if somebody has a solution for this please feel free to tell):
HTML
<input id="range" type="range" min="0" max="10"/>
<div id="rangeval">0</div>
JavaScript
function updateRangeVal(){
var offLeft = Math.floor(($('#range').val() / $('#range').attr('max')) * $('#range').width() - ((($('#range').val() / $('#range').attr('max')) * $('#range').width() - $('#range').width()/2) / 100) * 24);
var offLeftAbs = $('#range').offset().left - 8 + offLeft;
$('#rangeval').css({"top": ($('#range').offset().top-8)+"px", "left": offLeftAbs +"px"});
$('#rangeval').html($('#range').val());
}
$('#range').on('input', function(){
updateRangeVal();
});
updateRangeVal();
CSS
#rangeval{
position: absolute;
height: 16px;
width: 16px;
text-align: center;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
input[type=range]{
-webkit-appearance: none;
position: absolute;
left: 200px;
top: 300px;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 5px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: 1px solid #e95e57;
height: 32px;
width: 32px;
border-radius: 50%;
background: white;
margin-top: -14px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #ccc;
}
fiddle
the offsets on the slider are just for testing purposes