Skip to the content

Ring carousel

A carousel in the round. The cards stand on a ring seen from a little above, the one in front at full ink and the others veiled according to their depth.

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 whole ring is built from it. Leave air above the stage, where the far cards rise, and put no overflow, opacity or filter on the ring box, which would flatten it: clip on the section instead.
  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-ring-carousel Marks the section that holds the ring. 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 ring, the counter, the caption line and the buttons in. Without it on any section of the page, the embed marks the section holding each ring (data-ring-carousel-ring).
    data-ring-carousel-ring Marks the box that holds the cards, the one the engine turns. Without it the parent of the first marked card is taken; with neither, nothing is mounted and the console says so. [ Required ]
    data-ring-carousel-card Marks one card, a child of the ring. Three at least. Without it on any of them the engine takes the ring's own children as the cards. [ Optional ]
    data-ring-carousel-stage Marks the box the hand grabs, which also takes the wheel and the keyboard focus, and which the engine gives its perspective. Without it the parent of the ring is taken. [ Optional ]
    data-ring-carousel-caption Marks the caption of a card, inside it. With the script it is hidden in the card and shown in the display line when the card is in front. Without it the alt of the card's picture is used. [ Optional ]
    data-ring-carousel-display Marks the line that shows the caption of the card in front, which comes out of a mask at each change. Without it no caption is shown. [ Optional ]
    data-ring-carousel-current Marks the number of the card in front. The engine fills it with a reel that rolls as the ring turns. Without it there is no current number. [ Optional ]
    data-ring-carousel-total Marks the total of the counter, which the engine writes as the card count. Without it there is no total. [ Optional ]
    data-ring-carousel-prev Marks a button that steps the ring one card back. Without it the drag, the wheel and the arrow keys still do. [ Optional ]
    data-ring-carousel-next Marks a button that steps the ring one card further. Without it the drag, the wheel and the arrow keys still do. [ Optional ]
    data-ring-carousel-state Written by the engine on the section: ready, or still under reduced motion. Never written by hand; the stylesheet reads it to pile the cards on the ring and show the hand. [ Optional ]
    data-ring-carousel-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-ring-carousel-active Written by the engine on the card in front. Never written by hand; a rule of the page may read it. [ 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-ring-carousel-color #15100c Colour of the current number of the counter and of the caption, the ink in the cream and ink look. Options: any CSS colour; without the setting, --ring-carousel-color on the section takes over.
    data-ring-carousel-veil #15100c Colour of the veil laid over the cards according to their depth. Options: any CSS colour; the ink darkens the far cards, the colour of the page fades them into it; without the setting, --ring-carousel-veil on the section takes over.
    data-ring-carousel-dim 0.45 Opacity of the veil on the card at the very back, 0 to 1; a card on the side takes about a quarter of it.
    data-ring-carousel-tilt 10 How high the camera stands over the ring, in degrees; the far cards rise behind the one in front.
    data-ring-carousel-depth 5 Distance of the camera, in card widths.
    data-ring-carousel-gap 0.8 Space left between two cards along the ring, as a share of the card width; with the width and the number of cards it gives the radius.
    data-ring-carousel-friction 0.965 Share of its speed a spinning ring keeps from one frame to the next, at 60 frames a second.
    data-ring-carousel-snap 140 Stiffness of the spring that docks a card and that steps the ring from the keys, the buttons and a click.
    data-ring-carousel-autoplay 0 Time between two cards when the ring turns by itself, in seconds.

What it does

Ring carousel is a scroll animation for Webflow and vanilla JavaScript, with no library. Also called 3D ring carousel, 3D cylinder carousel or 3D circular carousel.

A carousel in the round. The cards stand on a ring seen from a little above, the one in front at full ink and the others veiled according to their depth. The hand grabs the ring, with the mouse or a finger, and throws it: the ring runs on with the speed it was given, loses it to friction with no notch as the cards go by, and docks on a card, a soft spring taking it for the last degrees. Under the ring, the number of the card in front rolls on a reel geared to the ring, and its caption comes out of a mask as the card comes in. A wheel pushes the ring, the arrow keys and two buttons step it card by card, and a click on a card that is not in front brings it there. The radius is worked out from the width of a card and their number, so the ring follows the page at every size. Under reduced motion the ring stands still and every input steps one card at once. No library: Pointer Events and one transform per frame, on a clock that sleeps at rest. Pattern type 3D carousel, cylinder carousel, rotating gallery.

Updated

Questions

Mark three levels with custom attributes: data-ring-carousel on the section, data-ring-carousel-ring on the box that holds the cards, and data-ring-carousel-card on each card, three at least. Settings go on the section, for instance data-ring-carousel-tilt="12".

No, it loads no library. The drag is read through Pointer Events and the ring is moved by one transform per frame, on a clock that sleeps at rest. The momentum after a throw and the spring that docks a card are computed by the engine.

There is no radius setting: the radius is worked out from the width of a card, the number of cards and data-ring-carousel-gap, the space between two cards as a share of the card width, 0.8 by default. At 0 the cards touch edge to edge, and a higher value gives a wider ring that takes more of the page. Give the card a fluid width and the ring follows it at every size.

Something on the ring box is flattening it: an overflow other than visible, an opacity under 1, a filter, a clip-path or a mask. The ring then becomes a flat picture and the cards overlap in markup order. Clip on the section instead.

No. The stage has touch-action: pan-y, so a vertical swipe scrolls the page and a sideways one turns the ring. A plain vertical mouse wheel is also left to the page whenever the page has somewhere to scroll, and the arrow keys step the ring one card at a time.