# Slider Input

> A premium range slider with expanding fill, drag grip, and keyboard control — polished form control for settings and value pickers.

**Definition:** Slider Input is a components UI animation from collections.html. It is built with HTML, CSS, and JavaScript, ships with a live preview, and is free to copy into personal and commercial projects.

## Facts
- Category: Components
- Stack: HTML, CSS, and JavaScript
- Added: 2026-08-05
- Canonical page: https://html.bosconvertpro.com/collection/slider-input
- Full-page preview: https://html.bosconvertpro.com/collection/slider-input/full
- Live demo: https://html.bosconvertpro.com/demos/slider-input/index.html
- Markdown mirror: https://html.bosconvertpro.com/collection/slider-input/index.md
- License: https://html.bosconvertpro.com/terms

## How to use
1. Open https://html.bosconvertpro.com/collection/slider-input/full to preview the animation in full screen.
2. Copy index.html, styles.css, and script.js from the code tabs on https://html.bosconvertpro.com/collection/slider-input.
3. Paste the files into your project and adjust timing, easing, and content as needed.

## FAQ
### What is Slider Input?

Slider Input is a components UI animation from collections.html. A premium range slider with expanding fill, drag grip, and keyboard control — polished form control for settings and value pickers.

### What is Slider Input built with?

Slider Input is built with HTML, CSS, and JavaScript. The source for every file is shown on the animation page and can be copied straight into your project.

### How do I use Slider Input in my project?

Open the animation page (https://html.bosconvertpro.com/collection/slider-input), preview it live, then copy index.html, styles.css, and script.js from the code tabs. Paste the files into your project and adjust timing, easing, and content as needed. A standalone demo runs at https://html.bosconvertpro.com/demos/slider-input/index.html.

### Is Slider Input free to use?

Yes. The Slider Input demo code may be used in personal and commercial projects. You may not resell or redistribute the collection itself as a competing template pack. Full terms: https://html.bosconvertpro.com/terms.

## Source — index.html
````html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Slider Input</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main class="scene">
      <div class="slider-wrap">
        <div class="slider-glow" data-glow aria-hidden="true"></div>
        <div
          class="slider"
          data-slider
          role="slider"
          aria-label="Value"
          aria-valuemin="0"
          aria-valuemax="100"
          aria-valuenow="29"
          aria-valuetext="29 percent"
          tabindex="0"
        >
          <div class="slider__track" data-track>
            <div class="slider__fill" data-fill>
              <div class="slider__grip" data-grip aria-hidden="true">
                <span class="slider__bar"></span>
              </div>
            </div>
            <span class="slider__value" data-value>29%</span>
          </div>
        </div>
      </div>
    </main>

    <script src="script.js"></script>
  </body>
</html>
````

## Source — styles.css
````css
/* ==========================================================================
   Slider Input — premium white + amber-orange
   ========================================================================== */

:root {
  --text: #1c1c1e;
  --text-muted: #8e8e93;
  --accent: #f97316;
  --accent-deep: #ea580c;
  --accent-bright: #fb923c;
  --accent-glow: rgba(249, 115, 22, 0.35);
  --slider-height: 56px;
  --slider-width: min(460px, calc(100vw - 48px));
  --slider-radius: 4px;
  --inset: 4px;
  --font: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.2, 0.64, 1);
  --progress: 0.29;
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
}

body {
  font-family: var(--font);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
  background: #f5f5f7;
}

/* Studio-like canvas */
.scene {
  position: relative;
  width: 100%;
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  overflow: hidden;
  background:
    radial-gradient(ellipse 100% 80% at 50% 0%, rgba(255, 255, 255, 0.95) 0%, transparent 55%),
    radial-gradient(ellipse 70% 50% at 50% 100%, rgba(0, 0, 0, 0.03) 0%, transparent 50%),
    linear-gradient(180deg, #fafafa 0%, #f0f0f2 100%);
}

.scene::before {
  content: "";
  position: absolute;
  width: min(720px, 90vw);
  height: 280px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -42%);
  background: radial-gradient(
    ellipse at center,
    rgba(249, 115, 22, 0.06) 0%,
    transparent 68%
  );
  pointer-events: none;
  opacity: calc(0.35 + var(--progress) * 0.65);
  transition: opacity 0.35s var(--ease);
}

/* ---------- Wrap + ambient glow ---------- */

.slider-wrap {
  position: relative;
  width: var(--slider-width);
  z-index: 2;
}

.slider-glow {
  position: absolute;
  left: 0;
  top: 50%;
  height: 48px;
  width: calc(28px + var(--progress) * (100% - 28px));
  max-width: 100%;
  transform: translateY(-40%);
  border-radius: 50%;
  background: radial-gradient(
    ellipse at center,
    rgba(249, 115, 22, 0.45) 0%,
    rgba(249, 115, 22, 0.12) 45%,
    transparent 72%
  );
  filter: blur(18px);
  opacity: calc(0.25 + var(--progress) * 0.55);
  pointer-events: none;
  z-index: 0;
  transition: width 0.12s var(--ease), opacity 0.25s var(--ease);
}

/* ---------- Slider shell ---------- */

.slider {
  position: relative;
  z-index: 1;
  width: 100%;
  height: var(--slider-height);
  outline: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  cursor: pointer;
  transform: translateY(0) scale(1);
  transition:
    transform 0.22s var(--ease-spring),
    filter 0.22s var(--ease);
  filter: drop-shadow(0 14px 28px rgba(0, 0, 0, 0.08))
    drop-shadow(0 4px 10px rgba(0, 0, 0, 0.04));
}

.slider:hover:not(.is-dragging) {
  filter: drop-shadow(0 16px 32px rgba(0, 0, 0, 0.09))
    drop-shadow(0 4px 12px rgba(0, 0, 0, 0.05));
}

.slider.is-dragging {
  cursor: pointer;
  transform: translateY(1px) scale(0.995);
  filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.07))
    drop-shadow(0 2px 6px rgba(0, 0, 0, 0.04));
}

/* Premium white porcelain track */
.slider__track {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: var(--slider-radius);
  overflow: hidden;
  isolation: isolate;

  background:
    linear-gradient(
      180deg,
      #ffffff 0%,
      #fcfcfd 42%,
      #f4f4f6 100%
    );

  border: 1px solid rgba(0, 0, 0, 0.06);
  box-shadow:
    0 0 0 0.5px rgba(255, 255, 255, 0.8),
    0 1px 0 rgba(255, 255, 255, 1),
    0 10px 30px rgba(0, 0, 0, 0.06),
    0 2px 8px rgba(0, 0, 0, 0.04),
    inset 0 2px 5px rgba(0, 0, 0, 0.035),
    inset 0 -1px 0 rgba(255, 255, 255, 0.9);
}

/* Inner rim polish */
.slider__track::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 4;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 -1px 0 rgba(0, 0, 0, 0.03),
    inset 1px 0 0 rgba(255, 255, 255, 0.5),
    inset -1px 0 0 rgba(0, 0, 0, 0.02);
}

/* Hairline border light */
.slider__track::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 4;
  border: 1px solid rgba(255, 255, 255, 0.65);
  mix-blend-mode: soft-light;
}

/* Premium amber-orange fill */
.slider__fill {
  position: absolute;
  top: var(--inset);
  left: var(--inset);
  bottom: var(--inset);
  width: 29%;
  min-width: 28px;
  max-width: calc(100% - var(--inset) * 2);
  height: auto;
  border-radius: calc(var(--slider-radius) - 1px);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 9px 0 0;
  overflow: hidden;
  transition: width 0s linear;

  background:
    /* top specular */
    linear-gradient(
      180deg,
      rgba(255, 255, 255, 0.48) 0%,
      rgba(255, 255, 255, 0.12) 32%,
      transparent 50%
    ),
    /* rich body */
    linear-gradient(
      105deg,
      #ea580c 0%,
      #f97316 38%,
      #fb923c 72%,
      #fdba74 100%
    );

  box-shadow:
    0 2px 8px rgba(234, 88, 12, 0.32),
    0 1px 2px rgba(0, 0, 0, 0.08),
    3px 0 10px rgba(234, 88, 12, 0.12),
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -2px 4px rgba(154, 52, 18, 0.28),
    inset 1px 0 0 rgba(255, 255, 255, 0.2),
    inset -1px 0 0 rgba(154, 52, 18, 0.12);
}

/* Liquid highlight */
.slider__fill::before {
  content: "";
  position: absolute;
  left: 8%;
  right: 14%;
  top: 2px;
  height: 42%;
  border-radius: 999px;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.65) 0%,
    rgba(255, 255, 255, 0.15) 55%,
    transparent 100%
  );
  filter: blur(0.3px);
}

/* Soft under-edge shade */
.slider__fill::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    transparent 0%,
    rgba(120, 40, 0, 0.12) 100%
  );
}

.slider:not(.is-dragging) .slider__fill {
  transition:
    width 0.12s var(--ease),
    box-shadow 0.25s var(--ease);
}

.slider.is-dragging .slider__fill {
  background:
    linear-gradient(
      180deg,
      rgba(255, 255, 255, 0.4) 0%,
      rgba(255, 255, 255, 0.1) 32%,
      transparent 50%
    ),
    linear-gradient(
      105deg,
      #dc2626 0%,
      #ea580c 35%,
      #f97316 70%,
      #fb923c 100%
    );
  box-shadow:
    0 1px 5px rgba(234, 88, 12, 0.28),
    0 1px 2px rgba(0, 0, 0, 0.08),
    2px 0 8px rgba(234, 88, 12, 0.1),
    inset 0 1px 0 rgba(255, 255, 255, 0.42),
    inset 0 -2px 5px rgba(127, 29, 29, 0.28),
    inset 1px 0 0 rgba(255, 255, 255, 0.15);
}

/* Grip */
.slider__grip {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 100%;
  flex-shrink: 0;
  cursor: pointer;
}

.slider.is-dragging .slider__grip {
  cursor: pointer;
}

/* Polished white handle */
.slider__bar {
  display: block;
  width: 3.5px;
  height: 22px;
  border-radius: 9999px;
  background: linear-gradient(
    90deg,
    #e8e8ed 0%,
    #ffffff 35%,
    #ffffff 65%,
    #ececf0 100%
  );
  box-shadow:
    0 2px 4px rgba(0, 0, 0, 0.18),
    0 0 0 0.5px rgba(0, 0, 0, 0.05),
    inset 0 1px 0 #ffffff,
    inset 0 -1px 0 rgba(0, 0, 0, 0.06),
    inset 1px 0 0 rgba(255, 255, 255, 0.9);
  pointer-events: none;
  transition:
    transform 0.18s var(--ease-spring),
    box-shadow 0.18s var(--ease),
    height 0.18s var(--ease);
}

.slider.is-dragging .slider__bar {
  height: 20px;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.16),
    0 0 0 0.5px rgba(0, 0, 0, 0.05),
    inset 0 1px 0 #ffffff,
    inset 0 -1px 0 rgba(0, 0, 0, 0.08);
}

/* Value label */
.slider__value {
  position: absolute;
  top: 50%;
  right: 18px;
  transform: translateY(-50%);
  z-index: 3;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--text-muted);
  line-height: 1;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
  transition:
    color 0.2s var(--ease),
    text-shadow 0.2s var(--ease),
    opacity 0.2s var(--ease);
}

.slider__value.is-on-fill {
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(120, 40, 0, 0.25);
}

.slider:focus-visible .slider__track {
  outline: 2px solid rgba(249, 115, 22, 0.45);
  outline-offset: 4px;
}

/* ---------- Responsive ---------- */

@media (max-width: 520px) {
  :root {
    --slider-height: 50px;
    --inset: 3px;
  }

  .slider__value {
    font-size: 13px;
    right: 14px;
  }

  .slider__fill {
    min-width: 26px;
    padding: 0 7px 0 0;
  }

  .slider__bar {
    height: 18px;
    width: 3px;
  }

  .slider.is-dragging .slider__bar {
    height: 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .slider,
  .slider__fill,
  .slider__bar,
  .slider-glow,
  .scene::before {
    transition: none !important;
  }
}
````

## Source — script.js
````javascript
/**
 * Premium slider — expanding orange fill, drag / click / keyboard.
 */

(() => {
  const slider = document.querySelector("[data-slider]");
  const track = document.querySelector("[data-track]");
  const fill = document.querySelector("[data-fill]");
  const valueEl = document.querySelector("[data-value]");
  const wrap = document.querySelector(".slider-wrap");
  const scene = document.querySelector(".scene");

  if (!slider || !track || !fill || !valueEl) return;

  const MIN = 0;
  const MAX = 100;
  const MIN_FILL_PX = 28;
  /** Matches CSS --inset * 2 */
  const INSET_PX = 8;

  let value = 29;
  let dragging = false;
  let trackWidthPx = 0;
  let raf = 0;

  function measure() {
    trackWidthPx = track.getBoundingClientRect().width;
  }

  function clamp(n, a, b) {
    return Math.min(b, Math.max(a, n));
  }

  function innerMax() {
    return Math.max(MIN_FILL_PX, trackWidthPx - INSET_PX);
  }

  function widthForValue(v) {
    measure();
    const maxW = innerMax();
    const t = clamp(v, MIN, MAX) / 100;
    return MIN_FILL_PX + t * (maxW - MIN_FILL_PX);
  }

  function valueFromClientX(clientX) {
    measure();
    const rect = track.getBoundingClientRect();
    const x = clientX - rect.left - INSET_PX / 2;
    const maxW = innerMax();
    const usable = Math.max(1, maxW - MIN_FILL_PX);
    const t = (x - MIN_FILL_PX) / usable;
    return clamp(Math.round(t * 100), MIN, MAX);
  }

  function render(v) {
    value = clamp(Math.round(v), MIN, MAX);
    const progress = value / 100;

    fill.style.width = `${widthForValue(value)}px`;
    valueEl.textContent = `${value}%`;
    valueEl.classList.toggle("is-on-fill", value >= 80);

    const root = document.documentElement;
    root.style.setProperty("--progress", String(progress));
    if (scene) scene.style.setProperty("--progress", String(progress));
    if (wrap) wrap.style.setProperty("--progress", String(progress));

    slider.setAttribute("aria-valuenow", String(value));
    slider.setAttribute("aria-valuetext", `${value} percent`);
  }

  function onPointerDown(e) {
    if (e.button != null && e.button !== 0) return;
    dragging = true;
    slider.classList.add("is-dragging");
    try {
      slider.setPointerCapture(e.pointerId);
    } catch (_) {
      /* ignore */
    }
    render(valueFromClientX(e.clientX));
    e.preventDefault();
  }

  function onPointerMove(e) {
    if (!dragging) return;
    if (raf) cancelAnimationFrame(raf);
    const x = e.clientX;
    raf = requestAnimationFrame(() => {
      render(valueFromClientX(x));
      raf = 0;
    });
  }

  function onPointerUp(e) {
    if (!dragging) return;
    dragging = false;
    slider.classList.remove("is-dragging");
    try {
      slider.releasePointerCapture(e.pointerId);
    } catch (_) {
      /* ignore */
    }
  }

  function onKeyDown(e) {
    let next = value;
    const step = e.shiftKey ? 10 : 1;
    switch (e.key) {
      case "ArrowRight":
      case "ArrowUp":
        next = value + step;
        break;
      case "ArrowLeft":
      case "ArrowDown":
        next = value - step;
        break;
      case "Home":
        next = MIN;
        break;
      case "End":
        next = MAX;
        break;
      case "PageUp":
        next = value + 10;
        break;
      case "PageDown":
        next = value - 10;
        break;
      default:
        return;
    }
    e.preventDefault();
    render(next);
  }

  measure();
  render(value);

  slider.addEventListener("pointerdown", onPointerDown);
  window.addEventListener("pointermove", onPointerMove);
  window.addEventListener("pointerup", onPointerUp);
  window.addEventListener("pointercancel", onPointerUp);
  slider.addEventListener("keydown", onKeyDown);

  window.addEventListener("resize", () => {
    measure();
    render(value);
  });
})();
````
