Elastic Bounce-Back Range Slider — HTML CSS JS Snippet

Elastic Bounce-Back Range Slider · Forms · Plain HTML, CSS & JS · Live preview

What's included

Features

Dragging past the min/max keeps moving the value, scaled down by a resistance factor, instead of hard-stopping
The track itself visually stretches (scaleX anchored at the pulled end) during an overshoot, not just the thumb
A spring easing curve (cubic-bezier with an overshooting control point) on release, reading as a genuine bounce
Resistance and visual stretch are computed from the same overshoot distance but serve independent purposes
Value is always clamped back into true range the instant the drag ends, regardless of how far it overshot
Full keyboard support with fine (1) and coarse (Shift+10) steps, unaffected by the elastic drag behavior

About this UI Snippet

Elastic Bounce-Back Range Slider — The Track Deforms, Not Just the Thumb

Screenshot of the Elastic Bounce-Back Range Slider snippet rendered live

Every other slider in this collection clamps hard at its min and max — the thumb simply can't go further. This one deliberately lets you *feel* that boundary instead: drag past either end and the value keeps moving, but scaled down by a RESISTANCE factor of 0.35, so it takes roughly three pixels of extra drag to move the value one further unit past the edge. At the same time, the track itself visibly stretches — a small scaleX anchored at whichever end is being pulled — so the *whole control* looks like it's being tugged, not just the thumb sliding past an invisible wall.

Resistance applied to the value, stretch applied to the track — same input, two outputs

One piece of state, the overshoot distance, drives both effects independently: value grows past MAX by only a fraction of the real drag distance (the resistance), while stretchTrack() separately converts that same overshoot into a small scaleX on the track element (the visual deformation). They're computed from the same numbers but serve different purposes — one keeps the *displayed value* from running away, the other gives *visual feedback* that something is being resisted.

A spring easing curve, not a linear snap-back

On release, both the thumb's left and the track's scaleX transition back using cubic-bezier(.34, 1.56, .64, 1) — a curve whose middle control point exceeds 1, which makes the transition briefly overshoot its target before settling, reading as a genuine spring bounce rather than a mechanical ease-out.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the RESISTANCE factor is applied to the value calculation while a separate scaleX calculation handles the track's visual stretch, and why using a cubic-bezier curve with a control point above 1 produces a genuine spring-overshoot effect rather than just a fast ease-out. It's also worth asking the assistant to add a subtle haptic-style visual pulse the moment the drag crosses from normal range into the resisted overshoot zone, or to make the resistance progressively stiffen the further past the boundary the drag goes, rather than staying at one constant factor.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a range slider with elastic resistance and a spring bounce-back at its boundaries, in plain HTML, CSS, and vanilla JavaScript — no library, no physics engine.

Requirements:
- A standard slider track and draggable thumb representing a value within a configurable min/max range, working like an ordinary slider when dragged within that valid range.
- When the thumb is dragged past the minimum or maximum boundary, the underlying value must continue changing in that direction but scaled down by a fixed resistance factor (a constant less than 1) applied to the raw overshoot distance, so it takes noticeably more drag distance to move the value further past the boundary than it does within the normal range — this resistance calculation must happen continuously during the drag, not only at release.
- Simultaneously, while the value is in this overshoot state, the track element itself must visibly deform using a CSS transform-based scale (not a width change) anchored at whichever end is currently being pulled, so the whole control appears to stretch toward the drag direction, not just the thumb moving past an invisible boundary.
- On pointer or touch release, the value must be immediately clamped back to the true valid min/max range, and both the thumb's position and the track's stretch transform must animate back to their normal resting state using an easing curve that produces a visible spring-like overshoot-then-settle motion, not a linear or purely decelerating snap-back.
- While actively dragging within the normal (non-overshoot) range, no stretch or resistance effects should apply at all — the slider must behave exactly like an ordinary drag slider in that case.
- Keyboard support (Left/Right/Up/Down arrow keys, with a modifier key producing a larger step) must move the value normally within the valid range and must not be affected by or trigger any of the elastic overshoot behavior, which only applies to pointer/touch dragging.
- The thumb must carry correct ARIA slider role and value attributes.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="ebr-wrap">
  <div class="ebr-track" id="ebrTrack">
    <div class="ebr-fill" id="ebrFill"></div>
    <div class="ebr-thumb" id="ebrThumb" tabindex="0" role="slider" aria-label="Value" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50"></div>
  </div>
  <div class="ebr-readout" id="ebrReadout">50</div>
  <p class="ebr-hint">Drag past either end — the track stretches, then springs back.</p>
</div>

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA slider appears at 50, centered, with a hint about dragging past the ends.
  2. 2
    Drag within the normal rangeIt behaves like a completely ordinary slider — no resistance, no stretch.
  3. 3
    Drag past either endThe value keeps creeping (slowly) and the track visibly stretches toward that side.
  4. 4
    ReleaseBoth the thumb and the track spring back to the true boundary with a bouncy overshoot.
  5. 5
    Tune the feelAdjust the RESISTANCE constant to make the overshoot drag feel stiffer or looser.

Real-world uses

Common Use Cases

Tactile settings sliders
Give a plain numeric control real physical presence — brightness, volume, zoom level.
Playful onboarding or demo controls
A slider that rewards experimentation with a satisfying bounce at its limits.
Mobile-style native-feeling inputs
Mimic the elastic overscroll feel native iOS/Android controls are known for.
Learning elastic/spring interaction design
A clear, minimal example of resistance-scaled dragging plus a spring-easing release.

Got questions?

Frequently Asked Questions

Change the RESISTANCE constant (0 to 1) — a smaller number means the value barely moves at all when dragged past the edge (stiffer resistance), a larger number lets it move almost as freely as within the normal range (looser resistance).

Adjust the cubic-bezier values used in both the thumb's left transition and resetTrack()'s transform transition — increasing the second control point's y-value (currently 1.56) exaggerates the overshoot; bringing it closer to 1 produces a gentler settle.

transform: scaleX is a compositor-only property that animates smoothly without triggering layout, unlike animating width directly — important since the stretch effect updates on every pointermove during an active drag.

No — value is always clamped back into the true MIN/MAX range the instant the pointer is released, so the elastic overshoot is purely a drag-time visual and tactile effect, never a value the slider can actually end up holding.

The thumb carries role="slider" with proper aria-valuemin/max/now, and is fully operable via Left/Right/Up/Down (plus Shift for larger steps) without a mouse — keyboard interaction is entirely unaffected by the elastic drag behavior, which only applies to pointer/touch dragging.