符合品牌形象的範圍滑桿

使用原生範圍輸入

請使用加上標籤的 <input type="range">,而不是使用 <div> 元素或自訂指標處理常式重新建立滑桿。原生控制項會保留鍵盤和指標互動、觸控行為和無障礙支援。根據用途設定 min、max、step 和 value。

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

如果值需要格式化標籤或單位,請在一般 DOM 內容中公開,並在變更時更新 aria-valuetext。請勿在滑桿虛擬元素上使用 ::before 或 ::after,因為表單控制項上產生的內容無法互通。如果需要跟隨滑桿的工具提示,請使用 CSS 錨定定位將其錨定至滑桿;如需在翻轉時保持正確方向的工具提示,請參閱位置感知工具提示。

選擇樣式設定方法

如要簡單自訂顏色,請使用品牌一致表單,並保留瀏覽器的原生算繪功能:

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

accent-color 不是完整的滑桿樣式 API。對滑桿、軌道和填滿效果的影響取決於使用者代理程式。如需控制軌道、滑桿、尺寸、形狀或填滿效果,請使用下列虛擬元素。

設定軌道和滑桿樣式

使用 appearance: none、margin: 0 和 border: 0 重設預設 OS 樣式。如要標準化跨瀏覽器算繪,請在不同的規則區塊中宣告 WebKit 和 Firefox 虛擬元素,並使用 margin-block-start: calc((var(--slider-track-size) - var(--slider-thumb-size)) / 2) 將 WebKit 縮圖置中 (Firefox 會自動將縮圖置中)。將面向消費者的值保留為輸入內容的自訂屬性,這樣主題就不會直接指定虛擬元素。

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

移除原生外觀後,請務必提供可見的鍵盤焦點指標。請勿單獨使用顏色:

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

設定使用中活動追蹤的樣式

如果已填滿和未填滿的軌道部分樣式不同,Firefox 會透過 ::-moz-range-progress 顯示。WebKit/Blink 未提供對等的虛擬元素,因此請在 input 事件中將即時輸入值同步至 --control-value:

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

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

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

限制

  • 請勿將 WebKit 和 Firefox 虛擬選取器合併成單一逗號分隔的清單 (例如 ::-webkit-slider-thumb, ::-moz-range-thumb);如果瀏覽器遇到無法辨識的供應商虛擬元素,就會捨棄整個規則。

備用廣告

accent-color 的備用方案和瀏覽器支援

accent-color 屬性是漸進增強。不支援這項屬性的瀏覽器會忽略該屬性,並使用預設的使用者介面顏色。

progress() 和 attr() 的備用和瀏覽器支援

如果不支援 progress(),請使用 calc() 計算 --slider-progress:

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

如果瀏覽器不支援 attr() 類型,請在 JavaScript 中同步處理輸入內容的 min 和 max 屬性中的 --attr-min 和 --attr-max:

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