Menggunakan input rentang native
Gunakan <input type="range"> berlabel, bukan membuat ulang penggeser dengan elemen <div> atau pengendali pointer kustom. Kontrol native mempertahankan interaksi keyboard dan pointer, perilaku sentuh, serta dukungan aksesibilitas. Konfigurasikan min, max, step, dan value untuk kasus penggunaan.
<label for="range-slider">Volume</label>
<input type="range" id="range-slider" value="70"/>
Jika nilai memerlukan label atau unit yang diformat, ekspos nilai tersebut dalam konten DOM biasa dan perbarui aria-valuetext saat diubah. Jangan gunakan ::before atau ::after pada elemen pseudo penggeser, karena konten yang dihasilkan pada kontrol formulir tidak dapat dioperasikan. Jika diperlukan tooltip yang mengikuti thumb, posisikan tooltip ke thumb dengan pemosisian anchor CSS; lihat Tooltip yang Memperhatikan Posisi untuk tooltip yang tetap berorientasi dengan benar saat dibalik.
Memilih pendekatan gaya
Untuk penyesuaian warna sederhana, gunakan Formulir yang Konsisten dengan Merek dan pertahankan rendering native browser:
input[type="range"] {
accent-color: var(--brand-color);
}
accent-color bukan API gaya penggeser yang lengkap. Efeknya pada thumb, track, dan fill bergantung pada agen pengguna. Gunakan elemen semu di bawah saat trek, thumb, dimensi, bentuk, atau pengisian harus dikontrol.
Menata gaya trek dan thumb
Reset gaya OS default dengan appearance: none, margin: 0, dan border: 0. Untuk menormalisasi rendering lintas browser, deklarasikan elemen pseudo WebKit dan Firefox dalam blok aturan terpisah, dan pusatkan thumb WebKit menggunakan margin-block-start: calc((var(--slider-track-size) - var(--slider-thumb-size)) / 2) (Firefox memusatkan thumb secara otomatis). Pertahankan nilai yang ditujukan untuk konsumen sebagai properti kustom pada input sehingga tema tidak menargetkan elemen semu secara langsung.
input[type="range"] {
--slider-track-size: 0.5rem;
--slider-thumb-size: 1.25rem;
--slider-track-radius: 999px;
--slider-thumb-radius: 50%;
--slider-track-color: #d9d9d9;
--slider-fill-color: #06c;
--slider-thumb-color: var(--slider-fill-color);
--slider-direction: to right;
/* reverse gradient direction for right-to-left layouts */
&:dir(rtl) {
--slider-direction: to left;
}
/* Read min and max from attributes; --control-value is synced by the script below. */
--attr-min: attr(min type(<number>), 0);
--attr-max: attr(max type(<number>), 100);
--control-value: attr(value type(<number>), 50);
--slider-progress: calc(
progress(var(--control-value), var(--attr-min), var(--attr-max)) * 100%
);
appearance: none;
inline-size: 100%;
block-size: 2.5rem; /* Preserve a generous interaction area. */
margin: 0;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
cursor: pointer;
}
/* WebKit/Blink. */
input[type="range"]::-webkit-slider-runnable-track {
block-size: var(--slider-track-size);
border: 0;
border-radius: var(--slider-track-radius);
background: linear-gradient(
var(--slider-direction),
var(--slider-fill-color) var(--slider-progress),
var(--slider-track-color) var(--slider-progress)
);
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
inline-size: var(--slider-thumb-size);
block-size: var(--slider-thumb-size);
margin-block-start: calc(
(var(--slider-track-size) - var(--slider-thumb-size)) / 2
);
border: 0;
border-radius: var(--slider-thumb-radius);
background: var(--slider-thumb-color);
}
/* Firefox. */
input[type="range"]::-moz-range-track {
block-size: var(--slider-track-size);
border: 0;
border-radius: var(--slider-track-radius);
background: var(--slider-track-color);
}
input[type="range"]::-moz-range-progress {
block-size: var(--slider-track-size);
border-radius: var(--slider-track-radius);
background: var(--slider-fill-color);
}
input[type="range"]::-moz-range-thumb {
inline-size: var(--slider-thumb-size);
block-size: var(--slider-thumb-size);
border: 0;
border-radius: var(--slider-thumb-radius);
background: var(--slider-thumb-color);
}
Selalu sediakan indikator fokus keyboard yang terlihat setelah menghapus tampilan native. Jangan hanya menggunakan warna:
input[type="range"]:focus-visible {
outline: 2px solid var(--slider-fill-color);
outline-offset: 4px;
}
Menata gaya trek aktif
Jika bagian trek yang terisi diberi gaya yang berbeda dari trek yang tidak terisi, Firefox akan mengeksposnya melalui ::-moz-range-progress. WebKit/Blink tidak menyediakan elemen pseudo yang setara, jadi sinkronkan nilai input langsung ke --control-value pada peristiwa input:
const slider = document.querySelector('#range-slider');
function syncSliderValue() {
slider.style.setProperty('--control-value', slider.value);
}
syncSliderValue();
slider.addEventListener('input', syncSliderValue);
Batasan
- Jangan gabungkan pseudo-selector WebKit dan Firefox menjadi satu comma separated list (misalnya,
::-webkit-slider-thumb, ::-moz-range-thumb); browser akan menghapus seluruh aturan jika menemukan pseudo-element vendor yang tidak dikenali.
Pengganti
Penggantian & dukungan browser untuk accent-color
Properti accent-color adalah progressive enhancement.
Browser yang tidak mendukung properti ini akan mengabaikannya dan menggunakan warna UI default.
Penggantian & dukungan browser untuk progress() dan attr()
Jika progress() tidak didukung, hitung --slider-progress dengan calc():
@supports not (opacity: progress(1, 0, 100)) {
input[type="range"] {
--slider-progress: calc(
(var(--control-value) - var(--attr-min)) /
(var(--attr-max) - var(--attr-min)) * 100%
);
}
}
Jika attr() yang diketik tidak didukung, sinkronkan --attr-min dan --attr-max dari atribut min dan max input di JavaScript:
function syncSliderValue() {
slider.style.setProperty('--attr-min', slider.min || 0);
slider.style.setProperty('--attr-max', slider.max || 100);
slider.style.setProperty('--control-value', slider.value);
}