How to customize Input slider to make volume bar - javascript

I'm trying to make volume bar with input slider with styled-components.
I could find many useful information but cannot find about how to customize valued area.
For example, if I set volume as 80, default html input range color from 0 to 80 blue. I want to change this color but couldn't find any information about it. When I set -webkit-appearance: none; I could find it becomes transparent but I just want to change colors of it. (Not the background. I know I can do that with background).
edit) This is my code
const StyledTrackVolumeSlide = styled.input`
width: 100%;
// -webkit-appearance: none; I know this code will reset default css
background: #555;
height: 0.25em;
outline: none;
&::-webkit-slider-thumb {
-webkit-appearance: none;
}
I tried these properties, but could not find one with the blue valued background color. And also cannot find in chrome dev tools. Tried all the stuffs from here
&::-webkit-slider-thumb{
}
&:focus{
}
&::-ms-track{
}
Is there any possible way to customize input slider's valued color with plain CSS?

Check out this tool: https://toughengineer.github.io/demo/slider-styler
Among other things it allows to style progress indication.
To make the slider vertical you'll have to use CSS transform, though.
Here is an 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.2em;
-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 * 2em + var(--ratio) * (100% - 2em));
}
input[type=range].styled-slider:focus {
outline: none;
}
/*webkit*/
input[type=range].styled-slider::-webkit-slider-thumb {
width: 2em;
height: 2em;
border-radius: 1em;
background: #007cf8;
border: none;
box-shadow: 0 0 2px black;
margin-top: calc(max((1em - 1px - 1px) * 0.5,0px) - 2em * 0.5);
-webkit-appearance: none;
}
input[type=range].styled-slider::-webkit-slider-runnable-track {
height: 1em;
border-radius: 0.5em;
background: #efefef;
border: 1px solid #b2b2b2;
box-shadow: none;
}
input[type=range].styled-slider::-webkit-slider-thumb:hover {
background: #0061c3;
}
input[type=range].styled-slider:hover::-webkit-slider-runnable-track {
background: #e5e5e5;
border-color: #9a9a9a;
}
input[type=range].styled-slider::-webkit-slider-thumb:active {
background: #2f98f9;
}
input[type=range].styled-slider:active::-webkit-slider-runnable-track {
background: #f5f5f5;
border-color: #c1c1c1;
}
input[type=range].styled-slider.slider-progress::-webkit-slider-runnable-track {
background: linear-gradient(#007cf8,#007cf8) 0/var(--sx) 100% no-repeat, #efefef;
}
input[type=range].styled-slider.slider-progress:hover::-webkit-slider-runnable-track {
background: linear-gradient(#0061c3,#0061c3) 0/var(--sx) 100% no-repeat, #e5e5e5;
}
input[type=range].styled-slider.slider-progress:active::-webkit-slider-runnable-track {
background: linear-gradient(#2f98f9,#2f98f9) 0/var(--sx) 100% no-repeat, #f5f5f5;
}
/*mozilla*/
input[type=range].styled-slider::-moz-range-thumb {
width: 2em;
height: 2em;
border-radius: 1em;
background: #007cf8;
border: none;
box-shadow: 0 0 2px black;
}
input[type=range].styled-slider::-moz-range-track {
height: max(calc(1em - 1px - 1px),0px);
border-radius: 0.5em;
background: #efefef;
border: 1px solid #b2b2b2;
box-shadow: none;
}
input[type=range].styled-slider::-moz-range-thumb:hover {
background: #0061c3;
}
input[type=range].styled-slider:hover::-moz-range-track {
background: #e5e5e5;
border-color: #9a9a9a;
}
input[type=range].styled-slider::-moz-range-thumb:active {
background: #2f98f9;
}
input[type=range].styled-slider:active::-moz-range-track {
background: #f5f5f5;
border-color: #c1c1c1;
}
input[type=range].styled-slider.slider-progress::-moz-range-track {
background: linear-gradient(#007cf8,#007cf8) 0/var(--sx) 100% no-repeat, #efefef;
}
input[type=range].styled-slider.slider-progress:hover::-moz-range-track {
background: linear-gradient(#0061c3,#0061c3) 0/var(--sx) 100% no-repeat, #e5e5e5;
}
input[type=range].styled-slider.slider-progress:active::-moz-range-track {
background: linear-gradient(#2f98f9,#2f98f9) 0/var(--sx) 100% no-repeat, #f5f5f5;
}
/*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: 2em;
height: 2em;
border-radius: 1em;
background: #007cf8;
border: none;
box-shadow: 0 0 2px black;
margin-top: 0;
box-sizing: border-box;
}
input[type=range].styled-slider::-ms-track {
height: 1em;
border-radius: 0.5em;
background: #efefef;
border: 1px solid #b2b2b2;
box-shadow: none;
box-sizing: border-box;
}
input[type=range].styled-slider::-ms-thumb:hover {
background: #0061c3;
}
input[type=range].styled-slider:hover::-ms-track {
background: #e5e5e5;
border-color: #9a9a9a;
}
input[type=range].styled-slider::-ms-thumb:active {
background: #2f98f9;
}
input[type=range].styled-slider:active::-ms-track {
background: #f5f5f5;
border-color: #c1c1c1;
}
input[type=range].styled-slider.slider-progress::-ms-fill-lower {
height: max(calc(1em - 1px - 1px),0px);
border-radius: 0.5em 0 0 0.5em;
margin: -1px 0 -1px -1px;
background: #007cf8;
border: 1px solid #b2b2b2;
border-right-width: 0;
}
input[type=range].styled-slider.slider-progress:hover::-ms-fill-lower {
background: #0061c3;
border-color: #9a9a9a;
}
input[type=range].styled-slider.slider-progress:active::-ms-fill-lower {
background: #2f98f9;
border-color: #c1c1c1;
}
<input type="range" class="styled-slider slider-progress" style="width: 25em;" />
<br />
<!--this div is needed to cut off all that's not needed, you have to specify width explicitly-->
<div style="display: inline-block; width: 2.2em; overflow: hidden;">
<!--this div catches the size of the child block-->
<div style="display: inline-block;">
<!--this div sizes itself to the width of the <input> and makes itself square, also rotates contents-->
<div style="display: inline-block; height: 0; padding: 0 0 100% 0; transform: rotate(-90deg);">
<!--style <input> as usual as if it is horizontal-->
<input type="range" class="styled-slider slider-progress" style="width: 10em;" />
</div>
</div>
</div>
more content to the right of the vertical slider

"default html input range color" doesn't exist, the element is rendered by your browser.
You must specify -webkit-appearance: none; (depends browser), for telling to the browser "don't design the input, I take care of that".
another tutorial
Sadly you must recreate input element, you can't just override color.

Related

How do I get my etch-a-sketch program to "listen" to this dropdown menu instead of the buttons?

I'm new to Stack Overflow. I hope that I'm doing this correctly. ❤
I'm working on an old Etch-a-Sketch JavaScript project from months ago and decided to rework the 'mobile' form of the project because I hadn't bothered to do so at the time. At first, I tried just moving the buttons to the top horizontally, but I didn't like any of the variations I tried. So I decided I'd be better off with a dropdown menu instead that would appear when the screen is 500px or smaller, replacing the buttons.
The dropdown menu is supposed to do exactly what the buttons do - when a certain mode is selected, that's the mode that the program is supposed to switch to. For example, when the "Party mode" button is clicked, the program switches to "party mode". I want the dropdown menu to behave similarly - when the "party mode" option is selected, the program should switch to "party mode".
My logic was that I needed a function that grabbed the value of the dropdown menu, and then an "if" condition would run that pretty much says "If the value is x, x mode should run; else if the value is y, y mode should run", and so on. I added the function to the existing window.onload function so it would run upon the window loading. This didn't work.
Note that the dropdown menu will, in the future, only appear when the screen size is 500px or less. In addition, I still have the buttons on the screen for all sizes, just for testing/debugging purposes. When I'm done and have this figured out, the buttons will have "display = 'none'" and be hidden for the "mobile size".
Anyway, so yeah, the program is still just listening to the buttons, and not the dropdown menu. That leads me to believe that I need to somehow turn "off" the button mode? If that's the case, how do I do that? If that's not the case, what am I supposed to do here? Any help or insight would be greatly appreciated. Thanks!
const defaultMode = 'default';
const defaultSize = 30;
const defaultColor = '#0b478b';
let currentMode = defaultMode;
let currentSize = defaultSize;
let currentColor = defaultColor;
// Sets the program's current mode
function setCurrentMode(newMode) {
activeButton(newMode);
currentMode = newMode;
}
// Sets the grid's size
function setCurrentSize(newSize) {
currentSize = newSize;
}
// Sets the color of the square (if in default mode)
function setCurrentColor(newColor) {
currentColor = newColor;
}
// Links the various HTML elements to this script
const sizeValue = document.querySelector('#sizevalue');
const sizeSlider = document.querySelector('#sizeslider');
const colorPicker = document.querySelector('#colorpicker');
const defaultBtn = document.querySelector('#default');
const partyBtn = document.querySelector('#party');
const grayBtn = document.querySelector('#grayscale');
const eraserBtn = document.querySelector('#eraser');
const clearBtn = document.querySelector('#clear');
const grid = document.querySelector('#maincontainer');
// DOM manipulations for buttons, color picker, and size slider
colorPicker.onchange = (e) => setCurrentColor(e.target.value);
defaultBtn.onclick = () => setCurrentMode('default');
partyBtn.onclick = () => setCurrentMode('party');
grayBtn.onclick = () => setCurrentMode('gray');
eraserBtn.onclick = () => setCurrentMode('eraser');
clearBtn.onclick = () => reloadGrid();
sizeSlider.onmousemove = (e) => updateSizeValue(e.target.value);
sizeSlider.onchange = (e) => changeSize(e.target.value);
// When the size is changed, we set the grid size, update the size value (text), and reload the grid.
function changeSize(num) {
setCurrentSize(num);
updateSizeValue(num);
reloadGrid();
}
// When we update the size value, the text changes to reflect the value. (It's a square, so the value is always the same for length and width).
function updateSizeValue(num) {
sizeValue.innerHTML = `${num} x ${num}`;
}
// When we reload the grid (which happens when "Clear grid" is pressed), we ensure that we clear the grid and that the size is still the current size.
function reloadGrid() {
clearGrid()
makeGrid(currentSize)
}
// When we clear the grid, it clears the grid.
function clearGrid() {
grid.innerHTML = ''
}
// Creates the base grid and includes the code that says "when the mouse goes over the squares, draw."
function makeGrid(size) {
grid.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
grid.style.gridTemplateRows = `repeat(${size}, 1fr)`;
for (i = 0; i < size * size; i++) {
let square = document.createElement('div');
square.addEventListener('mouseover', changeColor);
grid.appendChild(square);
}
}
// These are the conditions to set the color of the "pen" (squares)
function changeColor(e) {
if (currentMode === 'party') {
const randomR = Math.floor(Math.random() * 256);
const randomG = Math.floor(Math.random() * 256);
const randomB = Math.floor(Math.random() * 256);
e.target.style.backgroundColor = `rgb(${randomR}, ${randomG}, ${randomB})`;
} else if (currentMode === 'default') {
e.target.style.backgroundColor = currentColor;
} else if (currentMode === 'gray') {
e.target.style.backgroundColor = calculateGray(e);
} else if (currentMode === 'eraser') {
e.target.style.backgroundColor = 'white';
}
}
// Shading mode code
function calculateGray(e) {
let clr = returnRGB(e.target.style.backgroundColor);
if (!clr || clr[1] !== clr[2] || clr[1] !== clr[3]) {
return `rgb(255, 255, 255)`;
}
return clr[1] <= 0 ? `rgb(255, 255, 255)` : `rgb(${clr[1]-25}, ${clr[1]-25}, ${clr[1]-25})`;
}
function returnRGB(num) {
return num.match(/rgb\(([0-9]*), ([0-9]*), ([0-9]*)\)/);
}
// Changes the button styling to indicate which mode is the active mode
function activeButton(newMode) {
if (currentMode === 'party') {
partyBtn.classList.remove('active');
} else if (currentMode === 'default') {
defaultBtn.classList.remove('active');
} else if (currentMode === 'gray') {
grayBtn.classList.remove('active');
} else if (currentMode === 'eraser') {
eraserBtn.classList.remove('active');
}
if (newMode === 'party') {
partyBtn.classList.add('active');
} else if (newMode === 'default') {
defaultBtn.classList.add('active');
} else if (newMode === 'gray') {
grayBtn.classList.add('active');
} else if (newMode === 'eraser') {
eraserBtn.classList.add('active');
}
}
// Ensures that, when we load the page, we make the grid and activate the correct mode (default).
window.onload = () => {
makeGrid(defaultSize);
activeButton(defaultMode);
dropdownModeThing(document.getElementById('dropdown-mode').value);
}
// Code for the dropdown menu
function dropdownModeThing(val) {
if (val === 'default') {
setCurrentMode('default');
} else if (val === 'party') {
setCurrentMode('party');
} else if (val === 'shading') {
setCurrentMode('gray');
} else if (val === 'eraser') {
setCurrentMode('eraser');
} else if (val === 'clear') {
reloadGrid();
}
}
body,
html {
min-height: 100vh;
height: 100%;
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
margin: 0;
padding: 0;
background-color: white;
overflow-x: hidden;
}
header {
text-align: center;
margin: 0;
border-bottom: 1px solid black;
background-color: #0b478b;
color: white;
padding: 10px;
box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}
p {
margin: 0;
}
h1 {
text-align: center;
margin: 0;
font-size: 2.5rem;
padding: 0;
}
#maincontainer {
background-color: white;
margin: 20px auto 10px auto;
display: grid;
border: 1px solid black;
width: 45vw;
height: 45vw;
min-height: 300px;
min-width: 300px;
box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}
.testing {
padding-top: 100%;
color: hsla(0, 0%, 68%, 0.596);
}
#btncontainer {
padding-top: 20px;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
a {
color: #2aa5a1;
text-decoration: none;
}
a:hover {
color: white;
}
button {
background-color: #2aa5a1;
color: white;
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
border: 1px solid black;
margin: 10px 15px;
padding: 8px 10px;
font-size: .9em;
transition: 0.3s;
box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}
button:active {
background-color: #3F86D8;
color: white;
border: 1px solid black;
}
.active {
background-color: #3F86D8;
transition: 0.3s;
color: white;
border: 1px solid black;
}
button:hover {
background-color: #0b478b;
color: white;
border: 1px solid black;
opacity: 1;
}
#rightside {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
text-align: center;
min-height: 500px;
padding: 0;
margin: 0;
}
#sizevalue {
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
margin-bottom: 0;
}
input[type=range] {
background-color: white;
height: 28px;
-webkit-appearance: none;
margin: 0;
margin-bottom: 35px;
width: 250px;
padding: 0;
}
input[type=range]:focus {}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 11px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000;
background: #3F86D8;
border-radius: 13px;
border: 0px solid #010101;
}
input[type=range]::-webkit-slider-thumb {
box-shadow: 1px 1px 2px #000031;
border: 1px solid #00001E;
height: 20px;
width: 20px;
border-radius: 15px;
background: #FFFFFF;
cursor: pointer;
-webkit-appearance: none;
margin-top: -5px;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #3F86D8;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 11px;
cursor: pointer;
animate: 0.2s;
box-shadow: 1px 1px 1px #000000;
background: #3F86D8;
border-radius: 13px;
border: 0px solid #010101;
}
input[type=range]::-moz-range-thumb {
box-shadow: 1px 1px 2px #000031;
border: 1px solid #00001E;
height: 20px;
width: 20px;
border-radius: 15px;
background: #F3EEED;
cursor: pointer;
}
input[type=range]::-ms-track {
width: 100%;
height: 11px;
cursor: pointer;
animate: 0.2s;
background: transparent;
border-color: transparent;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #3F86D8;
border: 0px solid #010101;
border-radius: 26px;
box-shadow: 1px 1px 1px #000000;
}
input[type=range]::-ms-fill-upper {
background: #3F86D8;
border: 0px solid #010101;
border-radius: 26px;
box-shadow: 1px 1px 1px #000000;
}
input[type=range]::-ms-thumb {
margin-top: 1px;
box-shadow: 1px 1px 2px #000031;
border: 1px solid #00001E;
height: 20px;
width: 20px;
border-radius: 15px;
background: #F3EEED;
cursor: pointer;
}
input[type=range]:focus::-ms-fill-lower {
background: #3F86D8;
}
input[type=range]:focus::-ms-fill-upper {
background: #3F86D8;
}
main {
display: flex;
justify-content: center;
margin: 0;
margin-bottom: 20px;
padding: 0;
}
#colorpicker {
-webkit-appearance: none;
border-radius: 100vw;
width: 50px;
height: 50px;
padding: 0;
margin: 0 auto 10px auto;
overflow: hidden;
border: 1px solid black;
box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}
input[type='color']:hover {
transform: scale(1.05);
}
input[type='color']::-webkit-color-swatch-wrapper {
padding: 0;
}
input[type='color']::-webkit-color-swatch {
border: none;
border-radius: 50px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
/* If you want dots under the hoverable text */
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px 0;
border-radius: 6px;
/* Position the tooltip text - see examples below! */
position: absolute;
z-index: 1;
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
}
.tooltip .tooltiptext::after {
content: " ";
position: absolute;
top: 50%;
right: 100%;
/* To the left of the tooltip */
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent black transparent transparent;
}
footer {
color: white;
text-align: center;
background-color: #0b478b;
position: fixed;
bottom: 0;
width: 100%;
margin: 0;
padding-top: 10px;
padding-bottom: 15px;
}
#media (max-width: 500px) {
main {
flex-direction: column;
}
#btncontainer {
margin: 0 auto;
padding: 20px 10px 5px 10px;
flex-wrap: wrap;
flex-direction: row;
justify-content: center;
}
#btncontainer button {
margin: 0 3px;
height: 35px;
}
#colorpicker {
-webkit-appearance: none;
border-radius: 100px;
width: 35px;
height: 35px;
padding: 0;
margin: 0 auto 10px auto;
overflow: hidden;
border: 1px solid black;
box-shadow: rgba(0, 0, 0, 0.15) 0px 3px 3px 0px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- CSS spreadsheet -->
<link href="styles.css" rel="stylesheet">
<title>Etch-a-Sketch</title>
</head>
<body>
<!-- Note that this is set up in various divs so
that we can use Flex to create our wanted layout. -->
<div id="entirepage">
<header>
<h1>Etch-a-Sketch</h1>
<p title="Testing">Select a color or a different mode, then select your size, and get drawing!</p>
</header>
<main>
<div id="btncontainer">
<select id="dropdown-mode">
<option value="default">Default mode</option>
<option value="party">Party mode</option>
<option value="shading">Shading</option>
<option value="eraser">Eraser mode</option>
<option value="clear">Clear grid</option>
</select>
<input type="color" id="colorpicker" value="#0b478b">
<button id="default">Default mode</button>
<button id="party">Party mode</button>
<button id="grayscale">Shading</button>
<button id="eraser">Eraser mode</button>
<button id="clear">Clear grid</button>
</div>
<div id="rightside">
<div id="maincontainer">
</div>
<label for="sizeslider" id="sizevalue">30 x 30</label>
<input type="range" min="1" max="100" value="30" id="sizeslider">
</div>
</main>
<footer>
<p>Created by Sara Dunlop (RiscloverYT)</p>
</footer>
</div>
<!-- JavaScript script -->
<script src="script.js"></script>
</body>
</html>
Luckily, there's an easy way to do that. Add this piece of code into your javascript file and see the magic.
const dropdown = document.getElementById('dropdown-mode');
dropdown.addEventListener('change', (e) => {
setCurrentMode(e.target.value);
});
Read more about change event here.

Range Slider React hover, pressed and focus

I have a range slider made with React(Babel) and CSS. I am trying to figure out how to add hover, active and focus effects(Changing the color of the thumb and left side of the slider). I have tried directly adding :hover to input[type='range']::-webkit-slider-thumb but that doesn't work. I believe my main issue is stemming from the fact that the left part of the slider is styled with a box-shadow but I haven't found any other ways to handle this in documentation or Googling. Any help or suggestions are appreciated!
HTML:
<div id="root"></div>
CSS:
input[type='range'] {
-webkit-appearance: none;
background-color: #ddd;
height: 10px;
overflow: hidden;
width: 300px;
border-radius: 5px;
outline: none;
}
input[type='range']::-webkit-slider-runnable-track {
-webkit-appearance: none;
height: 10px;
}
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
background: #333;
border-radius: 50%;
box-shadow: -205px 0 0 200px red;
cursor: pointer;
height: 10px;
width: 10px;
border: 0;
}
input[type='range']::-moz-range-thumb {
background: #333;
border-radius: 50%;
box-shadow: -1005px 0 0 1000px red;
cursor: pointer;
height: 10px;
width: 10px;
border: 0;
}
input[type="range"]::-moz-range-track {
background-color: #ddd;
}
input[type="range"]::-moz-range-progress {
background-color: red;
height: 10px
}
input[type="range"]::-ms-fill-upper {
background-color: #ddd;
}
input[type="range"]::-ms-fill-lower {
background-color: red;
}
JavaScript(Babel)
class VolumeSlider extends React.Component {
constructor() {
super();
this.state = {
value: 12.5
};
}
onUpdate(e) {
this.setState({
value: e.target.value
});
}
render() {
return (
<div className="mb1">
<input
className="c-input--range"
list="tickmarks"
max={100}
onChange={(e) => this.onUpdate(e)}
step={0.1}
type="range"
value={this.state.value}
/>
<div>
<label className="c-label">{this.state.value}</label>
</div>
</div>
);
}
}
ReactDOM.render(
<div>
<VolumeSlider />
</div>,
document.getElementById("root")
);
Code also provided in CodePen below. Thank you!
https://codepen.io/kcandle/pen/KKMrZKo
You want to assign variables for the colors of the box-shadow
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
--slider-thumb-background-color: #000;
background: var(--slider-thumb-background-color);
border-radius: 50%;
--box-shadow-color: orange;
box-shadow: -205px 0 0 200px var(--box-shadow-color);
cursor: pointer;
height: 10px;
width: 10px;
--border-color: orange;
border: 3px solid var(--border-color);
}
input[type='range']::-webkit-slider-thumb:hover {
--slider-thumb-background-color: grey;
--box-shadow-color: red;
--border-color: red;
}
input[type='range']::-webkit-slider-thumb:active {
--slider-thumb-background-color: white;
--box-shadow-color: blue;
--border-color: blue;
}

How to make the left side of a range slider a different color than the right side of the slider?

Looking for information on how to change the slider color depending upon what side of the dragable portion it is on, such as how the HTML5 video player slider does.
I've looked around for a bit and haven't found anything for pure JS solutions, only JQUERY, which I can't use. Any suggestions?
Depending on the design you can achieve this with pure CSS too:
input[type='range'] {
-webkit-appearance: none;
background-color: #ddd;
height: 20px;
overflow: hidden;
width: 400px;
}
input[type='range']::-webkit-slider-runnable-track {
-webkit-appearance: none;
height: 20px;
}
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
background: #333;
border-radius: 50%;
box-shadow: -210px 0 0 200px #666;
cursor: pointer;
height: 20px;
width: 20px;
border: 0;
}
input[type='range']::-moz-range-thumb {
background: #333;
border-radius: 50%;
box-shadow: -1010px 0 0 1000px #666;
cursor: pointer;
height: 20px;
width: 20px;
border: 0;
}
input[type="range"]::-moz-range-track {
background-color: #ddd;
}
input[type="range"]::-moz-range-progress {
background-color: #666;
height: 20px
}
input[type="range"]::-ms-fill-upper {
background-color: #ddd;
}
input[type="range"]::-ms-fill-lower {
background-color: #666;
}
<input type="range"/>
Using this you'll have to be aware of the input width and matching the box-shadow of the slider-thumb to be more than the width. As the box-shadow around the thumb is what is giving the appearance of different colours either side.
Also as this utilises overflow: hidden on the input you would not be able to have a bigger thumb than track.
Hence if the design is more specific I can also recommend noUISlider it doesn't use jQuery

js to determine responsive element width

I am new to js and have hit a brick wall with altering how I calculate an element width depending on the screen size. I started with only calculating the width by how many of the list items were set to "plan-visible". It works great on a laptop screen, but doesn't break at css media query widths when the screen is smaller. I then had the brilliant idea (haha) of attempting to this directly in the javascript with an if/else statement, which I have little experience with. The result was that it did absolutely nothing. I researched and researched and it looks (to me) like it should work, but I am obviously missing something. I have included the html, the original js that worked for a static element, and then my failed attempt at making it responsive. Thanks!
html:
<div id="product-table" class="clear">
<div class="plan-visible">
<h3>BALANCE<em>aap</em><img class="image aap" src="http://localhost:1400/images/baap.png"></h3>
<a class="sbutton aap" href="">Go to AAP</a>
<ul>
<li>Point and click your way through the preparation of your organization’s Affirmative Action plan.<br> </li>
</ul>
</div>
<div class="plan-visible">
<h3>BALANCE<em>trak</em><img class="image trak" src="http://localhost:1400/images/btrak.png"></h3>
<a class="sbutton trak" href="">Learn More</a>
<ul>
<li>Manage your organization’s hiring process from start to finish.<br> <br> </li>
</ul>
</div>
<div class="plan-visible">
<h3>BALANCE<em>hub</em><img class="image hub" src="http://localhost:1400/images/bhub.png"></h3>
<a class="sbutton hub" href="">Go to HUB</a>
<ul>
<li>Access a centralized compliance information center to view, publish, and share information from your BALANCEworks applications.</li>
</ul>
</div>
<div class="plan-visible">
<h3>BALANCE<em>pay</em><img class="image pay" src="http://localhost:1400/images/bpay.png"></h3>
<a class="sbutton" href="">Go to PAY</a>
<ul>
<li>Conduct detailed compensation analyses, identify potential pay discrimination, and design a compliant pay structure</li>
</ul>
</div>
</div>
original js:
$(document).ready(function() {
var width = 0;
$('.plan-visible').each(function() {
width += $(this).outerWidth( true );
});
$('#product-table').css('width', width);
});
new, broken js:
$(document).ready(function() {
var mq = window.matchMedia( "(max-width: 500px)" );
if (mq.matches) {
$('#product-table').css('446', width);
} else {
var width = 0;
$('.plan-visible').each(function() {
width += $(this).outerWidth( true );
});
$('#product-table').css('width', width);
}
});
css:
#product-table {
margin: 100px auto;
text-align: center;
.plan-visible {
font: 12px 'Lucida Sans', 'trebuchet MS', Arial, Helvetica;
text-shadow: 0 1px rgba(255,255,255,.8);
background: #fff;
border: 1px solid #ddd;
color: #333;
padding: 20px;
float: left;
position: relative;
-moz-border-radius: 5px ;
-webkit-border-radius: 5px;
border-radius: 5px ; }
.plan-visible:nth-child(1) {width: 180px;}
.plan-visible:nth-child(2) {width: 180px;}
.plan-visible:nth-child(3) {width: 180px;}
.plan-visible:nth-child(4) {width: 180px;}
.plan-hidden {display: none;}
}
/* --------------- */
#product-table h3 {
font-size: 20px;
color: $mainBlue;
font-weight: normal;
padding: 20px;
margin: -20px -20px 50px -20px;
background-color: $lightGrey;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
/* product image settings */
#product-table .plan-visible .image {
display: block;
height: 100px;
width: 100px;
margin: 15px auto -65px;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
border-radius: 100px;
}
#product-table .plan-visible .image.aap {
border: 3px solid $aap;
}
#product-table .plan-visible .image.trak {
border: 3px solid $trak;
}
#product-table .plan-visible .image.hub {
border: 3px solid $hub;
}
#product-table .plan-visible .image.pay {
border: 3px solid $pay;
}
/* --------------- */
#product-table ul {
margin: 20px 0 0 0;
padding: 0;
list-style: none;
}
#product-table li {
border-top: 1px solid $lightGrey;
padding: 20px 0 10px 0;
}
/* --------------- */
/* product table specific buttons */
.sbutton {
position: relative;
font-family: 'Roboto', Arial, sans-serif;
padding: 8px 20px;
margin: 20px 0 0 0;
display: inline-block;
background-color: $mainBlue;
color: white;
border-radius: 4px;
border: 1px solid $mainBlue;
text-align: center;
text-decoration: none;
font-size: 14px;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
cursor: pointer;
}
.sbutton:hover {
background-color: #94ae3c;
color: #fff;
border: 1px solid #94ae3c;
text-decoration: none;
}
.sbutton.aap:hover {
background-color: #6f2784;
border: 1px solid #6f2784;
}
.sbutton.trak:hover {
background-color: #5c89b4;
border: 1px solid #5c89b4;
}
.sbutton.hub:hover {
background-color: #b58f2e;
border: 1px solid #b58f2e;
}
.sbutton.pay:hover {
background-color: #94ae3c;
border: 1px solid #94ae3c;
}

How can I use a different color to fill the left side of the input[type="range"] in chrome using CSS?

As you can see below in IE the slider is working, but I can't find what is the "ms-fill-lower" pseudo-code in chrome/firefox. Also I haven't figured out how can I print out the number continously above the thumb (I was thinking about creating a new childnode in JS and then using the position of the slider + the current value of the thumb and with this info I could create a new position for the brand new childnode. Is there an easier way maybe?)
<!DOCTYPE:html>
<html>
<head>
<style>
input {
position: fixed;
top: 40;
right: 40;
}
input[type=range] {
-webkit-appearance: none;
margin: 30px 0px;
width: 80%;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-ms-thumb {
box-shadow: 0px 0px 0px #ffccff, 0px 0px 0px #ffccff;
height: 30px;
width: 48px;
background-image: url('https://scontent-vie1-1.xx.fbcdn.net/hphotos-xpa1/v/t34.0-12/12204684_1096899726988871_1886399559_n.jpg?oh=b8481694391b1a5ebe58733f0638a08f&oe=563669C2');
cursor: pointer;
-webkit-appearance: none;
margin-top: 0px;
}
input[type=range]::-ms-track {
width: 100%;
height: 30px;
cursor: pointer;
animate: 0.2s;
background: transparent;
border-color: transparent;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: #ff0000;
border: 0.2px solid #ff0000;
}
input[type=range]::-ms-fill-upper {
background: #ffccff;
}
input[type=range]:focus::-ms-fill-lower {
background: #ff0000;
}
input[type=range]:focus::-ms-fill-upper {
background: #ffccff;
}
</style>
</head>
<body>
<input type="range"></input>
</body>
</html>
Pseudo elements for chrome ::-webkit-slider-thumb and ::-webkit-slider-runnable-track
for firefox ::-moz-range-thumb and ::-moz-range-track
to print the number continuously
<input type="range" max="22" min="12" value="18" step="2" oninput="dataUpdate()" id="myInput" />
<p id="mydata"></p>
<script>
function dataUpdate(){
var x = document.getElementById("myInput").value;
document.getElementById("mydata").innerHTML=x;
}
</script>
where value is current position of the range on load, step is the difference between each value, oninput event will trigger when you'll move the range's thumb and the output will be displayed in the <p> tag
to check pseudo elements in chrome you can read this http://webcomponents.org/articles/introduction-to-shadow-dom/

Categories