Градиентная рамка для ползунка input type range
Есть input type range. У него нужно сделать градиентный фон для дорожки (это я сделал) и кружок, с градиентной рамкой, но вот беда, не нашел способа, как сделать ползунок в виде кружка с градиентной рамкой. Можно ли сделать это без js или хотя бы не имитируя работу ползунка при помощи js?
input[type=range] {
height: 24px;
-webkit-appearance: none;
margin: 10px 0;
width: 1052px;
margin-top: 167px;
position: relative;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 24px;
cursor: pointer;
background: linear-gradient(90deg, rgba(16,27,105,1) 0%, rgba(169,0,67,1) 100%);
border-radius: 20px;
border: 0px solid #ffffff;
z-index: 1;
}
input[type=range]::-webkit-slider-thumb {
border: 10px solid rgba(166,103,255,1);
height: 133px;
width: 133px;
border-radius: 50%;
background: #fff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -50px;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 24px;
cursor: pointer;
background: linear-gradient(90deg, rgba(16,27,105,1) 0%, rgba(169,0,67,1) 100%);
border-radius: 20px;
border: 0px solid #ffffff;
z-index: 1;
}
input[type=range]::-moz-range-thumb {
border: 10px solid rgba(166,103,255,1);
height: 133px;
width: 133px;
border-radius: 50%;
background: #fff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -50px;
}
input[type=range]::-ms-track {
width: 100%;
height: 24px;
cursor: pointer;
background: transparent;
border-color: transparent;
color: transparent;
}
input[type=range]::-ms-fill-lower {
background: linear-gradient(90deg, rgba(16,27,105,1) 0%, rgba(169,0,67,1) 100%);
border-radius: 20px;
}
input[type=range]::-ms-fill-upper {
background: linear-gradient(90deg, rgba(16,27,105,1) 0%, rgba(169,0,67,1) 100%);
border-radius: 20px;
}
input[type=range]::-ms-thumb {
border: 10px solid rgba(166,103,255,1);
height: 133px;
width: 133px;
border-radius: 50%;
background: #fff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -50px;
}
<input class="gradient" type="range" min="500" max="800000" value="250000" name="range" step="1">
Ответы (1 шт):
Можно ли сделать это без js или хотя бы не имитируя работу ползунка при помощи js?
Совсем без JS не получится. Но, без имитации и сложных скриптов, вполне возможно.
Для этого назначаем кнопке ползунка множественный фон и задаём необходимый градиент. Также, для удобства изменения значений в нескольких местах сразу, используем CSS-переменные (к тому же они используются в некоторых вычислениях).
Главный (и наверное единственный) минус - невозможность указать ширину в процентах.
const GRADIENT_RANGE = document.querySelector('.gradient');
GRADIENT_RANGE.addEventListener('input', function(ev) {
let percent = (100 * (+this.value - +this.min)) / (+this.max - +this.min);
this.style.setProperty('--percent', percent);
});
GRADIENT_RANGE.dispatchEvent(new Event('input'));
input[type="range"] {
--width: 90vw;
/* --gradient: linear-gradient(90deg, #101b69 50%, #a90043 50%); оригинальный */
--gradient: linear-gradient(90deg, red, orange, yellow, lime, cyan, blue, purple);
--thumb-sz: 133px;
--thumb-br: 10px;
--thumb-bg:
50% 50% / 100% 100% radial-gradient(circle calc(var(--thumb-sz) / 2 - var(--thumb-br)), #fff 0 98%, #fff0 100%) no-repeat,
calc(var(--percent) * 1%) 0 / var(--width) 100% var(--gradient) no-repeat;
--track-h: 24px;
-webkit-appearance: none;
margin: calc(var(--thumb-sz) / 2) auto;
display: block;
width: var(--width);
}
input[type="range"]:focus { outline: none; }
input[type="range"]::-webkit-slider-runnable-track {
height: var(--track-h);
width: 100%;
border-radius: 1000px;
background: var(--gradient);
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
position: relative;
top: 50%;
height: var(--thumb-sz);
width: var(--thumb-sz);
border-radius: 50%;
transform: translateY(-50%);
background: var(--thumb-bg);
cursor: pointer;
}
input[type="range"]::-moz-range-track {
height: var(--track-h);
width: 100%;
border: none;
border-radius: 1000px;
background: var(--gradient);
cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
-webkit-appearance: none;
height: var(--thumb-sz);
width: var(--thumb-sz);
border: none;
border-radius: 50%;
background: var(--thumb-bg);
cursor: pointer;
}
input[type="range"]::-ms-track {
height: var(--track-h);
width: 100%;
cursor: pointer;
border-color: transparent;
color: transparent;
background: transparent;
}
input[type="range"]::-ms-fill-lower {
border-radius: 1000px;
background: var(--gradient);
}
input[type="range"]::-ms-fill-upper {
border-radius: 1000px;
background: var(--gradient);
}
input[type="range"]::-ms-thumb {
-webkit-appearance: none;
position: relative;
top: 50%;
height: var(--thumb-sz);
width: var(--thumb-sz);
border: none;
border-radius: 50%;
transform: translateY(-50%);
background: var(--thumb-bg);
cursor: pointer;
}
<input class="gradient" type="range" min="500" max="800000" value="250000" name="range" step="1">
Извините, но префиксы -ms- негде было протестировать :-)
в моем случае градиент у полоски и у ползунка должен быть различным. В добавок, градиент у ползунка не должен меняться при перемещении.
Тогда задача упрощается - убираем JS и добавляем треку и кнопке разные градиенты. В таком варианте, работает даже процентная ширина ползунка.
input[type="range"] {
--track-gradient: linear-gradient(90deg, #101b69 0%, #a90043 100%);
--thumb-gradient: conic-gradient(red, orange, yellow, lime, cyan, blue, purple, red);
--thumb-sz: 133px;
--thumb-br: 10px;
--thumb-bg:
50% 50% / 100% 100% radial-gradient(circle calc(var(--thumb-sz) / 2 - var(--thumb-br)), #fff 0 98%, #fff0 100%) no-repeat,
50% 50% / 100% 100% var(--thumb-gradient) no-repeat;
--track-h: 24px;
-webkit-appearance: none;
margin: calc(var(--thumb-sz) / 2) auto;
display: block;
width: 100%;
}
input[type="range"]:focus { outline: none; }
input[type="range"]::-webkit-slider-runnable-track {
height: var(--track-h);
width: 100%;
border-radius: 1000px;
background: var(--track-gradient);
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
position: relative;
top: 50%;
height: var(--thumb-sz);
width: var(--thumb-sz);
border-radius: 50%;
transform: translateY(-50%);
background: var(--thumb-bg);
cursor: pointer;
}
input[type="range"]::-moz-range-track {
height: var(--track-h);
width: 100%;
border: none;
border-radius: 1000px;
background: var(--track-gradient);
cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
-webkit-appearance: none;
height: var(--thumb-sz);
width: var(--thumb-sz);
border: none;
border-radius: 50%;
background: var(--thumb-bg);
cursor: pointer;
}
input[type="range"]::-ms-track {
height: var(--track-h);
width: 100%;
cursor: pointer;
border-color: transparent;
color: transparent;
background: transparent;
}
input[type="range"]::-ms-fill-lower {
border-radius: 1000px;
background: var(--track-gradient);
}
input[type="range"]::-ms-fill-upper {
border-radius: 1000px;
background: var(--track-gradient);
}
input[type="range"]::-ms-thumb {
-webkit-appearance: none;
position: relative;
top: 50%;
height: var(--thumb-sz);
width: var(--thumb-sz);
border: none;
border-radius: 50%;
transform: translateY(-50%);
background: var(--thumb-bg);
cursor: pointer;
}
<input class="gradient" type="range" min="500" max="800000" value="250000" name="range" step="1">