beta

Slosh Slider — <mv-slosh-slider>

A slider whose fill is liquid: the handle stays rigid under your finger while the liquid chases it on a soft spring, bumps into the end stops, tilts and ripples with its velocity. A complete form field (keyboard, ARIA, reset), or a tank when vertical.

CategoryForms
TypeWeb Component (<mv-slosh-slider>)
Statusbeta
Keywordsslider, range, liquid, physics, spring, gauge, tank, form-associated, tactile

When to use

Avoid when

Install

node scripts/add.mjs slosh-slider --out ./src/marvelous

AI agent with the Marvelous UI MCP server: install_components({ slugs: ["slosh-slider"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Files copied (dependencies included): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/form.js, core/motion.js, core/observe.js, components/slosh-slider/slosh-slider.js, components/slosh-slider/slosh-slider.css.

Usage

Canonical markup — start from it and customize with attributes, data-* and CSS variables:

<form id="mv-slosh-slider-demo" style="display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2rem 2.5rem;align-items:end;width:100%;max-width:640px">
  <div style="display:grid;gap:1.4rem">
    <mv-slosh-slider label="Volume" name="volume" value="64" suffix="%"></mv-slosh-slider>
    <mv-slosh-slider label="Monthly budget" name="budget" min="0" max="2000" step="50" value="850" prefix="$" slosh="0.85" style="--mv-slosh-slider-color:var(--mv-success);--mv-slosh-slider-color-2:color-mix(in oklch,var(--mv-success),black 15%)"></mv-slosh-slider>
    <mv-slosh-slider label="Brightness (classic)" name="brightness" value="30" suffix="%" slosh="0" style="--mv-slosh-slider-height:1.75rem"></mv-slosh-slider>
  </div>
  <mv-slosh-slider label="Tank" name="water" orientation="vertical" value="70" suffix=" L" max="120" slosh="0.9" style="--mv-slosh-slider-color:var(--mv-info);--mv-slosh-slider-color-2:color-mix(in oklch,var(--mv-info),black 22%)"></mv-slosh-slider>
  <div style="grid-column:1/-1;display:flex;gap:.6rem;align-items:center;flex-wrap:wrap">
    <button class="mv-button" data-size="sm" type="submit">Submit</button>
    <button class="mv-button" data-size="sm" data-variant="outline" type="reset">Reset</button>
    <output id="mv-slosh-slider-demo-out" style="font-size:.8rem;color:var(--mv-fg-muted)"></output>
  </div>
</form>
<script type="module">
  const form = document.getElementById("mv-slosh-slider-demo");
  const out = document.getElementById("mv-slosh-slider-demo-out");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    out.textContent = [...new FormData(form)].map(([k, v]) => `${k} = ${v}`).join(" · ");
  });
</script>

API

Attributes

NameTypeDefaultDescription
labelstringVisible label (and accessible name).
namestringForm field name.
valuenumberInitial value (also used on reset).
min / max / stepnumber0 / 100 / 1Bounds and step (the step sets the displayed precision).
sloshnumber0.6Inverse viscosity: 0 = classic slider, 1 = very fluid liquid (softer, less damped).
orientationhorizontal | verticalhorizontalvertical: a tank that fills from the bottom, with a sloshing horizontal surface.
prefix / suffixstringText around the displayed and announced value (e.g. suffix="%").
hide-valuebooleanHides the displayed value (it is still announced).
disabled / requiredbooleanForm states (a disabled fieldset is respected).

Properties

NameTypeDescription
valuestringValue (a string, like an input).
valueAsNumbernumberNumeric value.

Events

NameDescription
inputOn every change while dragging or using the keyboard.
changeOn release or after a key press.

CSS variables

NameDefaultDescription
--mv-slosh-slider-color / --mv-slosh-slider-color-2accent / darkened accentLiquid gradient.
--mv-slosh-slider-trackvar(--mv-bg-muted)Tube background.
--mv-slosh-slider-height2.75remThickness of the horizontal tube.
--mv-slosh-slider-width / --mv-slosh-slider-length4.75rem / 12remSize of the vertical tank.
--mv-slosh-slider-radiusfull (2xl when vertical)Tube radius.
--mv-slosh-slider-ratioSet by the component: position 0..1, for styling around it.

Accessibility

role=slider on the tube (focusable), aria-valuemin/max/now and formatted aria-valuetext; ←/→/↑/↓ (Shift ×10), Page↑/↓, Home/End. Form-associated (ElementInternals): submitted value, reset, disabled fieldset, <label for>. The liquid is decorative (SVG aria-hidden). Reduced motion: instant fill, no ripples.