Schuifregelaar voor bereik die consistent is met het merk

De native bereikinvoer gebruiken

Gebruik een gelabelde <input type="range"> in plaats van een schuifregelaar opnieuw te maken met <div>-elementen of aangepaste aanwijzerhandlers. De systeemeigen bedieningselementen behouden de interactie met het toetsenbord en de muisaanwijzer, het aanraakgedrag en de toegankelijkheidsondersteuning. Stel min, max, step en value in voor de use case.

<label for="range-slider">Volume</label>
<input type="range" id="range-slider" value="70"/>

Als de waarde een opgemaakt label of een opgemaakte eenheid vereist, maak je deze beschikbaar in gewone DOM-content en update je aria-valuetext als deze wordt gewijzigd. Gebruik ::before of ::after niet op pseudo-elementen van schuifregelaars, omdat gegenereerde content op formulierbedieningselementen niet interoperabel is. Als je een tooltip nodig hebt die de schuifregelaar volgt, veranker je deze aan de schuifregelaar met CSS-ankerpositionering. Ga naar Positiebewuste tooltips voor tooltips die de juiste richting behouden als ze worden omgedraaid.

De stijlbenadering kiezen

Gebruik formulieren die consistent zijn met het merk voor eenvoudige kleuraanpassing en behoud de native weergave van de browser:

input[type="range"] {
  accent-color: var(--brand-color);
}

accent-color is geen volledige API voor schuifregelaarstijlen. Het effect op de duim, het spoor en de vulling is afhankelijk van de user-agent. Gebruik de onderstaande pseudo-elementen als u de track, de duim, de afmetingen, de vorm of de vulling wilt beheren.

De track en de duim stylen

Reset de standaard OS-stijl met appearance: none, margin: 0 en border: 0. Als je de weergave in verschillende browsers wilt normaliseren, declareer je WebKit- en Firefox-pseudoelementen in afzonderlijke regelblokken en centreer je de WebKit-thumb met margin-block-start: calc((var(--slider-track-size) - var(--slider-thumb-size)) / 2) (Firefox centreert de thumb automatisch). Houd waarden die voor consumenten zichtbaar zijn als aangepaste eigenschappen in de invoer, zodat thema's niet rechtstreeks pseudoelementen targeten.

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);
}

Zorg altijd voor een zichtbare indicator voor toetsenbordfocus nadat je de systeemeigen weergave hebt verwijderd. Gebruik niet alleen kleur:

input[type="range"]:focus-visible {
  outline: 2px solid var(--slider-fill-color);
  outline-offset: 4px;
}

De stijl van de actieve track aanpassen

Als het gevulde gedeelte van de track anders is opgemaakt dan de niet-gevulde track, maakt Firefox dit beschikbaar via ::-moz-range-progress. WebKit/Blink bieden geen equivalent pseudo-element, dus synchroniseer de live invoerwaarde naar --control-value bij input-gebeurtenissen:

const slider = document.querySelector('#range-slider');

function syncSliderValue() {
  slider.style.setProperty('--control-value', slider.value);
}

syncSliderValue();
slider.addEventListener('input', syncSliderValue);

Beperkingen

  • Combineer WebKit- en Firefox-pseudoselectors niet in één door komma's gescheiden lijst (bijv. ::-webkit-slider-thumb, ::-moz-range-thumb). Browsers laten de hele regel vallen als ze een niet-herkend pseudoelement van een leverancier tegenkomen.

Reserves

Fallbacks en browserondersteuning voor accent-color

De property accent-color is progressive enhancement. Browsers die deze property niet ondersteunen, negeren deze en gebruiken de standaard UI-kleuren.

Fallbacks en browserondersteuning voor progress() en attr()

Als progress() niet wordt ondersteund, bereken je --slider-progress met 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%
    );
  }
}

Als het getypte attr() niet wordt ondersteund, synchroniseer je --attr-min en --attr-max van de kenmerken min en max van de invoer in 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);
}