Skip to the content

Drag slider

A row of cards driven by the hand, with the mouse or a finger.

Become a member to unlock the full effect today.

Join now

Already a member? Sign in

Documentation

  1. Copy to Webflow

    Add Geist and Geist Mono to your site's fonts (Site settings, Fonts, Google Fonts) before pasting: Webflow removes any font your site has not installed.

  2. Add custom CSS

    Give the cards a width: the row is a flex line that never wraps, and a card with none shrinks to its words. And leave the track's transform to the engine, which writes it every frame.
  3. Add custom JS

  4. Tune it

    Custom attributes
    Select the section on the canvas and open the Settings panel. Under Custom attributes, add a pair: the name on the left, the value on the right.
    Custom attributeWhat it does
    data-drag-slider Marks the section that holds the row. It takes no value: leave the value field empty. That section is what the engine mounts on, what carries the settings and the states, and what it looks for the viewport, the track and the counter in. Without it on any section of the page, the embed marks the section holding each row (data-drag-slider-track).
    data-drag-slider-viewport Marks the box that clips the row, the parent of the track, and the one the hand grabs. With the script it clips without scrolling and hands the vertical swipe to the page. Without it the parent of the track is taken. [ Optional ]
    data-drag-slider-track Marks the row that moves, the block holding the cards. Nothing is mounted without it, and the engine says so in the console. [ Required ]
    data-drag-slider-card Marks one card, a child of the track. Without it on any of them the engine takes the track's own children as the cards. [ Optional ]
    data-drag-slider-current Marks the number of the card the counter reads. The engine fills it with one rolling reel of digits per figure. Without it there is no current number. [ Optional ]
    data-drag-slider-total Marks the total of the counter, which the engine writes as the card count. Without it there is no total. [ Optional ]
    data-drag-slider-bar Marks the fill of the progress rule, which the engine grows from the left as the row goes. Without it there is no rule to fill. [ Optional ]
    data-drag-slider-state Written by the engine on the section: ready when the row is longer than its viewport, fit when it is not. Never written by hand; the stylesheet reads it to clip the row and show the hand. [ Optional ]
    data-drag-slider-dragging Written by the engine on the section while a drag runs. Never written by hand; the stylesheet reads it for the closed hand. [ Optional ]
    data-drag-slider-active Written by the engine on the card the counter reads. Never written by hand; the stylesheet reads it to put that card's number in ink. [ Optional ]
    Settings
    Every setting is a custom attribute too, added the same way and on the same section. An attribute always wins over the defaults written in the code.
    AttributeDefaultWhat it is
    data-drag-slider-glide 0.32 How long a throw takes to lose most of its speed, in seconds; the row runs on about glide times the release speed.
    data-drag-slider-settle 0.5 How long the row takes to come back from past an end, or to reach a card brought in by the keyboard, in seconds.
    data-drag-slider-stretch 0.55 How much the row gives when it is pulled or thrown past an end, 0 to 1.
    data-drag-slider-threshold 6 How far a press travels sideways, in pixels, before it becomes a drag; a shorter press is a click.

What it does

Drag slider is a scroll animation for Webflow and vanilla JavaScript, with no library. Also called draggable slider with momentum, draggable slider or drag carousel inertia.

A row of cards driven by the hand, with the mouse or a finger. Grabbed, the row follows the pointer; thrown, it runs on with the speed it was given, slows down on its own and comes to rest where that speed runs out. Pulled past either end it gives less and less, like rubber, and a spring brings it back without overshooting. A counter reads the card in front ("03 / 09") on rolling digits and a rule fills as the row goes. A press that does not travel stays a click, so the cards are real links; a drag never opens one, and a press on a row still running stops it where it is. A vertical swipe still scrolls the page, a trackpad or a wheel with shift moves the row, the arrow keys step from card to card, and under reduced motion the row follows the hand and nothing runs on. No library: Pointer Events and one transform per frame, on a clock that sleeps at rest. Pattern type draggable carousel, momentum scroll, flick slider.

Updated

Questions

Mark the section with the custom attribute data-drag-slider, then add data-drag-slider-viewport on the box that clips the row, data-drag-slider-track on the row and data-drag-slider-card on each card. Give the cards a width: the row is a flex line that never wraps, and a card with no width of its own shrinks to its words.

No. It needs no library and no build step: it runs on Pointer Events and one transform per frame, on a clock that sleeps at rest.

Set data-drag-slider-glide, the time a throw takes to lose most of its speed, 0.32 seconds by default. Lower and the row stops soon after the hand lets go; higher and it coasts far and long. data-drag-slider-stretch, 0.55 by default, is how much the row gives when pulled past an end, and 0 makes the ends a wall.

Yes. A press that travels less than threshold pixels, 6 by default, stays a click and opens its card. Past that it is a drag, and the click the browser would send on release is swallowed, so a drag never opens a card.

No. The viewport has touch-action: pan-y, so a vertical swipe on the row scrolls the page and a sideways one moves the row. The arrow keys move the focus from card to card, and under reduced motion the row follows the hand, stops where it is let go and never passes its ends.