لغزنده محدوده سازگار با نمانام

استفاده از ورودی محدوده بومی

به‌جای بازآفرینی لغزنده با عناصر <div> یا کنترل‌کننده‌های اشاره‌گر سفارشی، از <input type="range"> برچسب‌گذاری‌شده استفاده کنید. کنترل بومی تعامل صفحه‌کلید و اشاره‌گر، رفتار لمسی، و پشتیبانی دسترس‌پذیری را حفظ می‌کند. ‫min،‏ max،‏ step، و value را برای مورد استفاده پیکربندی کنید.

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

اگر مقدار به برچسب یا واحد قالب‌بندی‌شده نیاز دارد، آن را در محتوای DOM معمولی نمایش دهید و aria-valuetext را هنگام تغییر به‌روز کنید. از ::before یا ::after در شبه‌عناصر لغزنده استفاده نکنید، زیرا محتوای تولیدشده در کنترل‌های فرم قابلیت همکاری ندارد. اگر به نکته‌ابزاری نیاز دارید که لغزنده را دنبال کند، آن را با CSS anchor positioning به لغزنده متصل کنید؛ برای نکته‌ابزارهایی که هنگام برگرداندن جهت درست خود را حفظ می‌کنند، به Position Aware Tooltips مراجعه کنید.

انتخاب رویکرد سبک‌بندی

برای سفارشی‌سازی ساده رنگ، از فرم‌های سازگار با نمانام استفاده کنید و رندرینگ بومی مرورگر را حفظ کنید:

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

‫accent-color یک میانای برنامه‌سازی کاربردی کامل برای سبک‌بندی لغزنده نیست. تأثیر آن بر لغزنده، شیار، و پر کردن به نماینده کاربر بستگی دارد. وقتی که باید شیار، لغزنده، ابعاد، شکل، یا پر کردن کنترل شود، از شبه‌عناصر زیر استفاده کنید.

سبک‌بندی شیار و لغزنده

سبک‌پردازی پیش‌فرض سیستم‌عامل را با appearance: none، margin: 0، و border: 0 بازنشانی کنید. برای عادی‌سازی رندرینگ بین‌مرورگری، شبه‌عناصر 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 شبه‌عنصر معادل ارائه نمی‌دهد، بنابراین مقدار ورودی زنده را با --control-value در رویدادهای input همگام‌سازی کنید:

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() پشتیبانی نمی‌شود، --slider-progress را با 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%
    );
  }
}

وقتی attr() تایپ‌شده پشتیبانی نمی‌شود، --attr-min و --attr-max را از مشخصه‌های min و 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);
}