Bagaimana gaya input rentang HTML5 agar memiliki warna berbeda sebelum dan sesudah slider?
94
Saya ingin sisi kiri menjadi hijau dan sisi kanan menjadi abu-abu. Seperti yang digambarkan di atas akan menjadi PERFECT. Lebih disukai solusi CSS murni (hanya perlu khawatir tentang WebKit).
Hai deathangel908, solusi yang bagus. Saya hanya akan meningkatkan bagian bayangan kotak: box-shadow: -80px 0 0px 80px # 43e5f7;
Filip Witkowski
32
Masalah dengan ini di chrome adalah jika Anda ingin ibu jari lebih besar dari trek, maka bayangan kotak tumpang tindih dengan trek dengan tinggi ibu jari. Apakah ada cara untuk membatasi box-shadow di dalam trek?
mharris7190
1
Ini tidak berfungsi untuk input dengan lebar berbasis persentase. Ada yang punya solusi untuk itu?
@tenwest Wow, itu mengerikan. Terima kasih atas pembaruannya!
CodeF0x
50
Sementara jawaban yang diterima bagus secara teori, ini mengabaikan fakta bahwa ibu jari tidak bisa lebih besar dari ukuran trek tanpa dipotong oleh overflow: hidden. Lihat contoh cara menangani ini hanya dengan sedikit JS.
dapatkah Anda menyarankan saya ketika saya menambahkan max = 5 dalam HTML maka warna tidak terisi dengan benar
Husna
@Husna Saya telah memperpanjang jawaban ini untuk juga menangani atribut min max, semoga membantu.
htmn
1
@Husna Anda harus menghitung% sebagai perbedaan antara nilai maks dan min. Misalnya, jika Anda memiliki min: 0 dan maks: 10, Anda harus menggunakan, di JS :,+ this.value / (10-0)*100 +'%, #fff
Rosario Russo
4
@Rosario Russo Anda hanya perlu memperbaiki ini. Nilai di JS dengan(this.value-this.min)/(this.max-this.min)*100
Silvan
29
Ya, itu mungkin. Meskipun saya tidak akan merekomendasikannya karena input rangetidak benar-benar didukung dengan baik oleh semua browser karena merupakan elemen baru yang ditambahkan dalam HTML5 dan HTML5 hanyalah konsep (dan akan berlangsung lama) jadi sejauh menata mungkin bukan yang terbaik. pilihan.
Selain itu, Anda juga membutuhkan sedikit JavaScript. Saya mengambil kebebasan menggunakan pustaka jQuery untuk ini, untuk tujuan kesederhanaan.
Bukan itu pertanyaannya, apa yang saya perlu lakukan dengan css, pasti ada cara hanya dengan css.
Ipad
10
Anda dapat membuatnya berfungsi di Chrome tanpa JS ( jsfiddle.net/1xg1j3tw ). Untuk IE10 + Anda dapat menggunakan elemen semu -ms-fill-lower dan -ms-fill-upper.
Ales
1
@ Ales Anda harus memasukkannya ke dalam jawaban tambahan.
Luca Steeb
4
Perubahan .change(untuk on('input', func..jadi latar belakang akan berubah ketika pengguna menggerakkan ibu jari tidak hanya mouse ke atas.
Yami Odymel
10
Pembaruan kecil untuk yang ini:
jika Anda menggunakan yang berikut ini akan memperbarui dengan cepat daripada saat rilis mouse.
"ubah mousemove", fungsi "
<script>
$('input[type="range"]').on("change mousemove", function () {
var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));
$(this).css('background-image',
'-webkit-gradient(linear, left top, right top, '
+ 'color-stop(' + val + ', #2f466b), '
+ 'color-stop(' + val + ', #d3d3db)'
+ ')'
);
});</script>
Membangun di atas jawaban @ dargue3 , jika Anda ingin jempol lebih besar dari trek, Anda ingin sepenuhnya memanfaatkan <input type="range" />elemen dan pergi lintas browser, Anda memerlukan sedikit baris tambahan JS & CSS.
Pada Chrome / Mozilla Anda dapat menggunakan linear-gradientteknik, tetapi Anda perlu menyesuaikan rasio berdasarkan min, max, valueatribut seperti yang disebutkan di sini oleh @Attila O. . Anda perlu memastikan Anda tidak menerapkan ini di Edge, jika tidak, jempol tidak akan ditampilkan. @Geoffrey Lalloué menjelaskan hal ini lebih detail di sini .
Hal lain yang perlu disebutkan, adalah Anda perlu menyesuaikan rangeEl.style.height = "20px";pada IE / Older. Sederhananya ini karena dalam hal ini "ketinggian tidak diterapkan ke trek melainkan seluruh masukan termasuk ibu jari". biola
/**
* Sniffs for Older Edge or IE,
* more info here:
* https://stackoverflow.com/q/31721250/3528132
*/functionisOlderEdgeOrIE() {
return (
window.navigator.userAgent.indexOf("MSIE ") > -1 ||
!!navigator.userAgent.match(/Trident.*rv\:11\./) ||
window.navigator.userAgent.indexOf("Edge") > -1
);
}
functionvalueTotalRatio(value, min, max) {
return ((value - min) / (max - min)).toFixed(2);
}
functiongetLinearGradientCSS(ratio, leftColor, rightColor) {
return [
'-webkit-gradient(',
'linear, ',
'left top, ',
'right top, ',
'color-stop(' + ratio + ', ' + leftColor + '), ',
'color-stop(' + ratio + ', ' + rightColor + ')',
')'
].join('');
}
functionupdateRangeEl(rangeEl) {
var ratio = valueTotalRatio(rangeEl.value, rangeEl.min, rangeEl.max);
rangeEl.style.backgroundImage = getLinearGradientCSS(ratio, '#919e4b', '#c5c5c5');
}
functioninitRangeEl() {
var rangeEl = document.querySelector('input[type=range]');
var textEl = document.querySelector('input[type=text]');
/**
* IE/Older Edge FIX
* On IE/Older Edge the height of the <input type="range" />
* is the whole element as oposed to Chrome/Moz
* where the height is applied to the track.
*
*/if (isOlderEdgeOrIE()) {
rangeEl.style.height = "20px";
// IE 11/10 fires change instead of input// https://stackoverflow.com/a/50887531/3528132
rangeEl.addEventListener("change", function(e) {
textEl.value = e.target.value;
});
rangeEl.addEventListener("input", function(e) {
textEl.value = e.target.value;
});
} else {
updateRangeEl(rangeEl);
rangeEl.addEventListener("input", function(e) {
updateRangeEl(e.target);
textEl.value = e.target.value;
});
}
}
initRangeEl();
input[type="range"] {
-webkit-appearance: none;
-moz-appearance: none;
width: 300px;
height: 5px;
padding: 0;
border-radius: 2px;
outline: none;
cursor: pointer;
}
/*Chrome thumb*/input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
-moz-appearance: none;
-webkit-border-radius: 5px;
/*16x16px adjusted to be same as 14x14px on moz*/height: 16px;
width: 16px;
border-radius: 5px;
background: #e7e7e7;
border: 1px solid #c5c5c5;
}
/*Mozilla thumb*/input[type="range"]::-moz-range-thumb {
-webkit-appearance: none;
-moz-appearance: none;
-moz-border-radius: 5px;
height: 14px;
width: 14px;
border-radius: 5px;
background: #e7e7e7;
border: 1px solid #c5c5c5;
}
/*IE & Edge input*/input[type=range]::-ms-track {
width: 300px;
height: 6px;
/*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */background: transparent;
/*leave room for the larger thumb to overflow with a transparent border */border-color: transparent;
border-width: 2px0;
/*remove default tick marks*/color: transparent;
}
/*IE & Edge thumb*/input[type=range]::-ms-thumb {
height: 14px;
width: 14px;
border-radius: 5px;
background: #e7e7e7;
border: 1px solid #c5c5c5;
}
/*IE & Edge left side*/input[type=range]::-ms-fill-lower {
background: #919e4b;
border-radius: 2px;
}
/*IE & Edge right side*/input[type=range]::-ms-fill-upper {
background: #c5c5c5;
border-radius: 2px;
}
/*IE disable tooltip*/input[type=range]::-ms-tooltip {
display: none;
}
input[type="text"] {
border: none;
}
Solusi yang diterima sebelumnya tidak lagi berfungsi .
Saya akhirnya mengkodekan fungsi sederhana yang membungkusnya rangeke dalam wadah bergaya menambahkan bilah yang diperlukan sebelum kursor. Saya menulis contoh ini di mana mudah untuk melihat dua warna 'biru' dan 'oranye' diatur di css, sehingga mereka dapat dengan cepat dimodifikasi.
Jika Anda menggunakan jawaban pertama , ada masalah dengan ibu jari. Di chrome jika Anda ingin ibu jari lebih besar dari trek , maka bayangan kotak tumpang tindih dengan trek dengan tinggi ibu jari.
Cukup rangkum semua jawaban ini dan tulis slider yang biasanya berfungsi dengan jempol slider yang lebih besar: jsfiddle
const slider = document.getElementById("myinput")
const min = slider.min
const max = slider.max
const value = slider.value
slider.style.background = `linear-gradient(to right, red 0%, red ${(value-min)/(max-min)*100}%, #DEE2E6 ${(value-min)/(max-min)*100}%, #DEE2E6 100%)`
slider.oninput = function() {
this.style.background = `linear-gradient(to right, red 0%, red ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 100%)`
};
Jawaban:
Solusi CSS murni :
input[range]
, dan isi semua ruang kiri ke ibu jari dengan warna bayangan.::-ms-fill-lower
::-moz-range-progress
/*Chrome*/ @media screen and (-webkit-min-device-pixel-ratio:0) { input[type='range'] { overflow: hidden; width: 80px; -webkit-appearance: none; background-color: #9a905d; } input[type='range']::-webkit-slider-runnable-track { height: 10px; -webkit-appearance: none; color: #13bba4; margin-top: -1px; } input[type='range']::-webkit-slider-thumb { width: 10px; -webkit-appearance: none; height: 10px; cursor: ew-resize; background: #434343; box-shadow: -80px 0 0 80px #43e5f7; } } /** FF*/ input[type="range"]::-moz-range-progress { background-color: #43e5f7; } input[type="range"]::-moz-range-track { background-color: #9a905d; } /* IE*/ input[type="range"]::-ms-fill-lower { background-color: #43e5f7; } input[type="range"]::-ms-fill-upper { background-color: #9a905d; }
<input type="range"/>
sumber
Sementara jawaban yang diterima bagus secara teori, ini mengabaikan fakta bahwa ibu jari tidak bisa lebih besar dari ukuran trek tanpa dipotong oleh
overflow: hidden
. Lihat contoh cara menangani ini hanya dengan sedikit JS.// .chrome styling Vanilla JS document.getElementById("myinput").oninput = function() { this.style.background = 'linear-gradient(to right, #82CFD0 0%, #82CFD0 ' + this.value + '%, #fff ' + this.value + '%, white 100%)' };
#myinput { background: linear-gradient(to right, #82CFD0 0%, #82CFD0 50%, #fff 50%, #fff 100%); border: solid 1px #82CFD0; border-radius: 8px; height: 7px; width: 356px; outline: none; transition: background 450ms ease-in; -webkit-appearance: none; }
<div class="chrome"> <input id="myinput" type="range" value="50" /> </div>
sumber
+ this.value / (10-0)*100 +'%, #fff
(this.value-this.min)/(this.max-this.min)*100
Ya, itu mungkin. Meskipun saya tidak akan merekomendasikannya karena
input range
tidak benar-benar didukung dengan baik oleh semua browser karena merupakan elemen baru yang ditambahkan dalam HTML5 dan HTML5 hanyalah konsep (dan akan berlangsung lama) jadi sejauh menata mungkin bukan yang terbaik. pilihan.Selain itu, Anda juga membutuhkan sedikit JavaScript. Saya mengambil kebebasan menggunakan pustaka jQuery untuk ini, untuk tujuan kesederhanaan.
Ini dia: http://jsfiddle.net/JnrvG/1/ .
sumber
.change(
untukon('input', func..
jadi latar belakang akan berubah ketika pengguna menggerakkan ibu jari tidak hanya mouse ke atas.Pembaruan kecil untuk yang ini:
jika Anda menggunakan yang berikut ini akan memperbarui dengan cepat daripada saat rilis mouse.
"ubah mousemove", fungsi "
<script> $('input[type="range"]').on("change mousemove", function () { var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min')); $(this).css('background-image', '-webkit-gradient(linear, left top, right top, ' + 'color-stop(' + val + ', #2f466b), ' + 'color-stop(' + val + ', #d3d3db)' + ')' ); });</script>
sumber
Membangun di atas jawaban @ dargue3 , jika Anda ingin jempol lebih besar dari trek, Anda ingin sepenuhnya memanfaatkan
<input type="range" />
elemen dan pergi lintas browser, Anda memerlukan sedikit baris tambahan JS & CSS.Pada Chrome / Mozilla Anda dapat menggunakan
linear-gradient
teknik, tetapi Anda perlu menyesuaikan rasio berdasarkanmin
,max
,value
atribut seperti yang disebutkan di sini oleh @Attila O. . Anda perlu memastikan Anda tidak menerapkan ini di Edge, jika tidak, jempol tidak akan ditampilkan. @Geoffrey Lalloué menjelaskan hal ini lebih detail di sini .Hal lain yang perlu disebutkan, adalah Anda perlu menyesuaikan
rangeEl.style.height = "20px";
pada IE / Older. Sederhananya ini karena dalam hal ini "ketinggian tidak diterapkan ke trek melainkan seluruh masukan termasuk ibu jari". biola/** * Sniffs for Older Edge or IE, * more info here: * https://stackoverflow.com/q/31721250/3528132 */ function isOlderEdgeOrIE() { return ( window.navigator.userAgent.indexOf("MSIE ") > -1 || !!navigator.userAgent.match(/Trident.*rv\:11\./) || window.navigator.userAgent.indexOf("Edge") > -1 ); } function valueTotalRatio(value, min, max) { return ((value - min) / (max - min)).toFixed(2); } function getLinearGradientCSS(ratio, leftColor, rightColor) { return [ '-webkit-gradient(', 'linear, ', 'left top, ', 'right top, ', 'color-stop(' + ratio + ', ' + leftColor + '), ', 'color-stop(' + ratio + ', ' + rightColor + ')', ')' ].join(''); } function updateRangeEl(rangeEl) { var ratio = valueTotalRatio(rangeEl.value, rangeEl.min, rangeEl.max); rangeEl.style.backgroundImage = getLinearGradientCSS(ratio, '#919e4b', '#c5c5c5'); } function initRangeEl() { var rangeEl = document.querySelector('input[type=range]'); var textEl = document.querySelector('input[type=text]'); /** * IE/Older Edge FIX * On IE/Older Edge the height of the <input type="range" /> * is the whole element as oposed to Chrome/Moz * where the height is applied to the track. * */ if (isOlderEdgeOrIE()) { rangeEl.style.height = "20px"; // IE 11/10 fires change instead of input // https://stackoverflow.com/a/50887531/3528132 rangeEl.addEventListener("change", function(e) { textEl.value = e.target.value; }); rangeEl.addEventListener("input", function(e) { textEl.value = e.target.value; }); } else { updateRangeEl(rangeEl); rangeEl.addEventListener("input", function(e) { updateRangeEl(e.target); textEl.value = e.target.value; }); } } initRangeEl();
input[type="range"] { -webkit-appearance: none; -moz-appearance: none; width: 300px; height: 5px; padding: 0; border-radius: 2px; outline: none; cursor: pointer; } /*Chrome thumb*/ input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; -moz-appearance: none; -webkit-border-radius: 5px; /*16x16px adjusted to be same as 14x14px on moz*/ height: 16px; width: 16px; border-radius: 5px; background: #e7e7e7; border: 1px solid #c5c5c5; } /*Mozilla thumb*/ input[type="range"]::-moz-range-thumb { -webkit-appearance: none; -moz-appearance: none; -moz-border-radius: 5px; height: 14px; width: 14px; border-radius: 5px; background: #e7e7e7; border: 1px solid #c5c5c5; } /*IE & Edge input*/ input[type=range]::-ms-track { width: 300px; height: 6px; /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */ background: transparent; /*leave room for the larger thumb to overflow with a transparent border */ border-color: transparent; border-width: 2px 0; /*remove default tick marks*/ color: transparent; } /*IE & Edge thumb*/ input[type=range]::-ms-thumb { height: 14px; width: 14px; border-radius: 5px; background: #e7e7e7; border: 1px solid #c5c5c5; } /*IE & Edge left side*/ input[type=range]::-ms-fill-lower { background: #919e4b; border-radius: 2px; } /*IE & Edge right side*/ input[type=range]::-ms-fill-upper { background: #c5c5c5; border-radius: 2px; } /*IE disable tooltip*/ input[type=range]::-ms-tooltip { display: none; } input[type="text"] { border: none; }
<input type="range" value="80" min="10" max="100" step="1" /> <input type="text" value="80" size="3" />
sumber
Solusi yang diterima sebelumnya tidak lagi berfungsi .
Saya akhirnya mengkodekan fungsi sederhana yang membungkusnya
range
ke dalam wadah bergaya menambahkan bilah yang diperlukan sebelum kursor. Saya menulis contoh ini di mana mudah untuk melihat dua warna 'biru' dan 'oranye' diatur di css, sehingga mereka dapat dengan cepat dimodifikasi.sumber
Jika Anda menggunakan jawaban pertama , ada masalah dengan ibu jari. Di chrome jika Anda ingin ibu jari lebih besar dari trek , maka bayangan kotak tumpang tindih dengan trek dengan tinggi ibu jari.
Cukup rangkum semua jawaban ini dan tulis slider yang biasanya berfungsi dengan jempol slider yang lebih besar: jsfiddle
const slider = document.getElementById("myinput") const min = slider.min const max = slider.max const value = slider.value slider.style.background = `linear-gradient(to right, red 0%, red ${(value-min)/(max-min)*100}%, #DEE2E6 ${(value-min)/(max-min)*100}%, #DEE2E6 100%)` slider.oninput = function() { this.style.background = `linear-gradient(to right, red 0%, red ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 100%)` };
#myinput { border-radius: 8px; height: 4px; width: 150px; outline: none; -webkit-appearance: none; } input[type='range']::-webkit-slider-thumb { width: 6px; -webkit-appearance: none; height: 12px; background: black; border-radius: 2px; }
<div class="chrome"> <input id="myinput" type="range" min="0" value="25" max="200" /> </div>
sumber
Sekarang didukung dengan elemen semu di masing-masing WebKit, Firefox dan IE. Tapi, tentu saja, berbeda satu sama lain. : (
Lihat jawaban pertanyaan ini dan / atau cari CodePen berjudul
prettify <input type=range> #101
untuk beberapa solusi.sumber
input type="range" min="0" max="50" value="0" style="margin-left: 6%;width: 88%;background-color: whitesmoke;"
kode di atas mengubah gaya input rentang .....
sumber