Reputation: 533
I was following this method from CSS-Tricks to style an input range and was trying to use the before and after pseudo classes. Below is the code I have tried:
input[type=range]::-webkit-slider-thumb:before {
background: #fff;
}
This doesn't seem to do the trick. Can someone help me how to style the slider track. I need a pure CSS solution. Essentially I want it to look like this.
I will also paste the code from CSS-Tricks:
input[type=range] {
-webkit-appearance: none;
margin: 18px 0;
width: 100%;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3px;
border: 0.2px solid #010101;
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -14px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #367ebd;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
background: #3071a9;
border-radius: 1.3px;
border: 0.2px solid #010101;
}
input[type=range]::-moz-range-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
}
input[type=range]::-ms-track {
width: 100%;
height: 8.4px;
cursor: pointer;
animate: 0.2s;
background: transparent;
border-color: transparent;
border-width: 16px 0;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #2a6495;
border: 0.2px solid #010101;
border-radius: 2.6px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
background: #3071a9;
border: 0.2px solid #010101;
border-radius: 2.6px;
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
}
input[type=range]::-ms-thumb {
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
border: 1px solid #000000;
height: 36px;
width: 16px;
border-radius: 3px;
background: #ffffff;
cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
background: #3071a9;
}
input[type=range]:focus::-ms-fill-upper {
background: #367ebd;
}
Upvotes: 8
Views: 18691
Reputation: 691
If anybody is facing this same issue, here is a (selfmade) generator for generating the (pure) css for such a progress-bar:
https://antvil.github.io/css-sos/sos/progress/
Generated Example:
Tested for: firefox, chrome, edge, opera, safari
But be aware that it sometimes breaks for webkit browsers, because border-radius for the progress cannot be implemented
Upvotes: -1
Reputation: 345
it's possible! if your thumb does not have to be bigger than the progress bar.
some css wizard came up with this: https://codepen.io/noahblon/pen/OyajvN
it uses a box-shadow on the thumb to make the part before the thumb look a different color. important is that the range has overflow hidden to make it work thats why the thumb cant be bigger than the track.
body {
height: 100vh;
margin: 0;
display: flex;
}
input[type="range"] {
margin: auto;
-webkit-appearance: none;
position: relative;
overflow: hidden;
height: 40px;
width: 200px;
cursor: pointer;
border-radius: 0; /* iOS */
}
::-webkit-slider-runnable-track {
background: #ddd;
}
/*
* 1. Set to 0 width and remove border for a slider without a thumb
*/
::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px; /* 1 */
height: 40px;
background: #fff;
box-shadow: -100vw 0 0 100vw dodgerblue;
border: 2px solid #999; /* 1 */
}
::-moz-range-track {
height: 40px;
background: #ddd;
}
::-moz-range-thumb {
background: #fff;
height: 40px;
width: 20px;
border: 3px solid #999;
border-radius: 0 !important;
box-shadow: -100vw 0 0 100vw dodgerblue;
box-sizing: border-box;
}
::-ms-fill-lower {
background: dodgerblue;
}
::-ms-thumb {
background: #fff;
border: 2px solid #999;
height: 40px;
width: 20px;
box-sizing: border-box;
}
::-ms-ticks-after {
display: none;
}
::-ms-ticks-before {
display: none;
}
::-ms-track {
background: #ddd;
color: transparent;
height: 40px;
border: none;
}
::-ms-tooltip {
display: none;
}
<input type="range" value="25">
Upvotes: 3
Reputation: 548
As far as I know it is not possible to do progress indication (i.e. to have different styles on different sides of the handle) purely in CSS across browsers.
Here's an idea how to do it easily with a bit of javascript code:
https://css-tricks.com/sliding-nightmare-understanding-range-input/#the-range-progress-fill-component
Here's a tool that generates CSS based on that method:
https://toughengineer.github.io/demo/slider-styler
Example:
for (let e of document.querySelectorAll('input[type="range"].slider-progress')) {
e.style.setProperty('--value', e.value);
e.style.setProperty('--min', e.min == '' ? '0' : e.min);
e.style.setProperty('--max', e.max == '' ? '100' : e.max);
e.addEventListener('input', () => e.style.setProperty('--value', e.value));
}
/*generated with Input range slider CSS style generator (version 20201223)
https://toughengineer.github.io/demo/slider-styler*/
input[type=range].styled-slider {
height: 2.8em;
-webkit-appearance: none;
}
/*progress support*/
input[type=range].styled-slider.slider-progress {
--range: calc(var(--max) - var(--min));
--ratio: calc((var(--value) - var(--min)) / var(--range));
--sx: calc(0.5 * 2.8em + var(--ratio) * (100% - 2.8em));
}
input[type=range].styled-slider:focus {
outline: none;
}
/*webkit*/
input[type=range].styled-slider::-webkit-slider-thumb {
width: 2.8em;
height: 2.8em;
border-radius: 1.4em;
background: #1381A9;
border: 0.3em solid #FFFFFF;
box-shadow: none;
margin-top: calc(1em * 0.5 - max(2.8em * 0.5,0.3em));
-webkit-appearance: none;
}
input[type=range].styled-slider::-webkit-slider-runnable-track {
height: 1em;
border-radius: 0.5em;
background: #D0D0D0;
border: none;
box-shadow: none;
}
input[type=range].styled-slider::-webkit-slider-thumb:hover {
background: #0E6180;
}
input[type=range].styled-slider:hover::-webkit-slider-runnable-track {
background: #A8A8A8;
}
input[type=range].styled-slider::-webkit-slider-thumb:active {
background: #18A5D9;
}
input[type=range].styled-slider:active::-webkit-slider-runnable-track {
background: #DBDBDB;
}
input[type=range].styled-slider.slider-progress::-webkit-slider-runnable-track {
background: linear-gradient(#666666,#666666) 0/var(--sx) 100% no-repeat, #D0D0D0;
}
input[type=range].styled-slider.slider-progress:hover::-webkit-slider-runnable-track {
background: linear-gradient(#404040,#404040) 0/var(--sx) 100% no-repeat, #A8A8A8;
}
input[type=range].styled-slider.slider-progress:active::-webkit-slider-runnable-track {
background: linear-gradient(#8C8C8C,#8C8C8C) 0/var(--sx) 100% no-repeat, #DBDBDB;
}
/*mozilla*/
input[type=range].styled-slider::-moz-range-thumb {
width: max(calc(2.8em - 0.3em - 0.3em),0px);
height: max(calc(2.8em - 0.3em - 0.3em),0px);
border-radius: 1.4em;
background: #1381A9;
border: 0.3em solid #FFFFFF;
box-shadow: none;
}
input[type=range].styled-slider::-moz-range-track {
height: 1em;
border-radius: 0.5em;
background: #D0D0D0;
border: none;
box-shadow: none;
}
input[type=range].styled-slider::-moz-range-thumb:hover {
background: #0E6180;
}
input[type=range].styled-slider:hover::-moz-range-track {
background: #A8A8A8;
}
input[type=range].styled-slider::-moz-range-thumb:active {
background: #18A5D9;
}
input[type=range].styled-slider:active::-moz-range-track {
background: #DBDBDB;
}
input[type=range].styled-slider.slider-progress::-moz-range-track {
background: linear-gradient(#666666,#666666) 0/var(--sx) 100% no-repeat, #D0D0D0;
}
input[type=range].styled-slider.slider-progress:hover::-moz-range-track {
background: linear-gradient(#404040,#404040) 0/var(--sx) 100% no-repeat, #A8A8A8;
}
input[type=range].styled-slider.slider-progress:active::-moz-range-track {
background: linear-gradient(#8C8C8C,#8C8C8C) 0/var(--sx) 100% no-repeat, #DBDBDB;
}
/*ms*/
input[type=range].styled-slider::-ms-fill-upper {
background: transparent;
border-color: transparent;
}
input[type=range].styled-slider::-ms-fill-lower {
background: transparent;
border-color: transparent;
}
input[type=range].styled-slider::-ms-thumb {
width: 2.8em;
height: 2.8em;
border-radius: 1.4em;
background: #1381A9;
border: 0.3em solid #FFFFFF;
box-shadow: none;
margin-top: 0;
box-sizing: border-box;
}
input[type=range].styled-slider::-ms-track {
height: 1em;
border-radius: 0.5em;
background: #D0D0D0;
border: none;
box-shadow: none;
box-sizing: border-box;
}
input[type=range].styled-slider::-ms-thumb:hover {
background: #0E6180;
}
input[type=range].styled-slider:hover::-ms-track {
background: #A8A8A8;
}
input[type=range].styled-slider::-ms-thumb:active {
background: #18A5D9;
}
input[type=range].styled-slider:active::-ms-track {
background: #DBDBDB;
}
input[type=range].styled-slider.slider-progress::-ms-fill-lower {
height: 1em;
border-radius: 0.5em 0 0 0.5em;
margin: -undefined 0 -undefined -undefined;
background: #666666;
border: none;
border-right-width: 0;
}
input[type=range].styled-slider.slider-progress:hover::-ms-fill-lower {
background: #404040;
}
input[type=range].styled-slider.slider-progress:active::-ms-fill-lower {
background: #8C8C8C;
}
<input type="range" class="styled-slider slider-progress" style="width: 50em;" />
Upvotes: 0
Reputation: 324
It is possible in Firefox and IE -
// Mozilla
input[type="range"]::-moz-range-progress {
background: #cc1a1a;
height: 12px;
border-radius: 12px;
}
// IE
input[type="range"]::-ms-fill-lower {
background: #CC1A1A;
border: 0 solid #000101;
border-radius: 50px;
box-shadow: 0 0 0 #000000, 0 0 0 #0d0d0d;
}
input[type="range"]::-ms-fill-upper {
background: #c0c0c0;
border: 0 solid #000101;
border-radius: 50px;
box-shadow: 0 0 0 #000000, 0 0 0 #0d0d0d;
}
Only one way was for Chrome :before
and :after
, isn't supported any more (since March 2016). The best I found - is http://rangeslider.js.org/. Also it works fine with Angular JS - https://github.com/danielcrisp/angular-rangeslider
Upvotes: 3
Reputation: 11
Bit of a delayed reply here:
A pure CSS solution is not possible cross-browser here - IE is the only one that makes this possible via ::-ms-fill-lower
and ::-ms-fill-upper
For a full cross-browser solution you'll need to use js. There's an example here that updates CSS gradients with the input's value to do roughly what you're after: http://codepen.io/ryanttb/pen/fHyEJ
You can also find information about this in this answer to a similar question: Style lower and upper fill in HTML5 range input
Upvotes: 1