Używanie natywnego pola do wpisywania zakresu
Użyj oznaczonego etykietą elementu <input type="range"> zamiast odtwarzać suwak za pomocą elementów <div> lub niestandardowych modułów obsługi wskaźnika. Natywny element sterujący zachowuje interakcję z klawiaturą i wskaźnikiem, działanie dotykowe oraz obsługę ułatwień dostępu. Skonfiguruj min, max, step i value pod kątem przypadku użycia.
<label for="range-slider">Volume</label>
<input type="range" id="range-slider" value="70"/>
Jeśli wartość wymaga sformatowanej etykiety lub jednostki, udostępnij ją w zwykłej zawartości DOM i zaktualizuj aria-valuetext, gdy ulegnie zmianie. Nie używaj ::before ani ::after w pseudoelementach suwaka, ponieważ wygenerowana treść w elementach sterujących formularza nie jest interoperacyjna. Jeśli potrzebujesz etykietki, która podąża za suwakiem, zakotwicz ją do suwaka za pomocą pozycjonowania kotwicy CSS. Aby dowiedzieć się, jak tworzyć etykietki, które zachowują prawidłową orientację po odwróceniu, zapoznaj się z artykułem Etykietki uwzględniające pozycję.
Wybieranie metody stylizacji
Aby łatwo dostosować kolory, użyj formularzy zgodnych z marką i zachowaj natywne renderowanie przeglądarki:
input[type="range"] {
accent-color: var(--brand-color);
}
accent-color nie jest kompletnym interfejsem API do stylizacji suwaka. Jego wpływ na suwak, ścieżkę i wypełnienie zależy od klienta użytkownika. Użyj pseudoelementów poniżej, gdy chcesz kontrolować ścieżkę, miniaturę, wymiary, kształt lub wypełnienie.
Stylizacja ścieżki i suwaka
Zresetuj domyślny styl systemu operacyjnego za pomocą appearance: none, margin: 0 i border: 0. Aby znormalizować renderowanie w różnych przeglądarkach, zadeklaruj pseudoelementy WebKit i Firefox w osobnych blokach reguł i wyśrodkuj suwak WebKit za pomocą margin-block-start: calc((var(--slider-track-size) - var(--slider-thumb-size)) / 2) (Firefox wyśrodkowuje suwak automatycznie). Zachowaj wartości przeznaczone dla użytkowników jako właściwości niestandardowe w danych wejściowych, aby motywy nie były kierowane bezpośrednio na pseudoelementy.
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);
}
Po usunięciu natywnego wyglądu zawsze wyświetlaj widoczny wskaźnik zaznaczenia klawiatury. Nie używaj tylko koloru:
input[type="range"]:focus-visible {
outline: 2px solid var(--slider-fill-color);
outline-offset: 4px;
}
Styl ścieżki aktywności
Gdy wypełniona część ścieżki jest stylizowana inaczej niż niewypełniona, Firefox udostępnia ją za pomocą ::-moz-range-progress. WebKit/Blink nie udostępniają odpowiedniego pseudoelementu, więc zsynchronizuj bieżącą wartość wejściową z --control-value w przypadku zdarzeń input:
const slider = document.querySelector('#range-slider');
function syncSliderValue() {
slider.style.setProperty('--control-value', slider.value);
}
syncSliderValue();
slider.addEventListener('input', syncSliderValue);
Ograniczenia
- Nie łącz pseudoselektorów WebKit i Firefox w jedną listę rozdzieloną przecinkami (np.
::-webkit-slider-thumb, ::-moz-range-thumb). Przeglądarki odrzucają całą regułę, jeśli napotkają nierozpoznany pseudoelement dostawcy.
Wartości zastępcze
Kreacje zastępcze i obsługa koloru uzupełniającego w przeglądarkach
Właściwość accent-color jest progresywnym ulepszaniem.
Przeglądarki, które nie obsługują tej właściwości, zignorują ją i użyją domyślnych kolorów interfejsu.
Kreacje zastępcze i obsługa przeglądarek w przypadku progress() i attr()
Gdy progress() nie jest obsługiwany, oblicz --slider-progress za pomocą 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%
);
}
}
Jeśli wpisany attr() nie jest obsługiwany, zsynchronizuj --attr-min i --attr-max z atrybutów min i max danych wejściowych w języku 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);
}