webdevpuneet.com

Vertical Story-Style Slider — HTML CSS JS Snippet

Vertical Story-Style Slider · Mobile · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<div class="vst-phone" id="vstPhone">
  <div class="vst-bars" id="vstBars"></div>
  <div class="vst-header">
    <img class="vst-avatar" src="https://i.pravatar.cc/60?img=32" alt="">
    <div class="vst-who"><strong>webdevpuneet</strong><span>2h ago</span></div>
  </div>
  <div class="vst-slides" id="vstSlides">
    <div class="vst-slide" style="background:linear-gradient(160deg,#6366f1,#4338ca)"><h2>New tool just dropped 🚀</h2><p>Build sitemaps in one click.</p></div>
    <div class="vst-slide" style="background:linear-gradient(160deg,#ec4899,#9d174d)"><h2>1788+ snippets</h2><p>Copy-paste HTML, CSS &amp; JS, free.</p></div>
    <div class="vst-slide" style="background:linear-gradient(160deg,#0ea5e9,#0369a1)"><h2>Export anywhere</h2><p>React, Vue, Angular &amp; Tailwind.</p></div>
    <div class="vst-slide" style="background:linear-gradient(160deg,#10b981,#047857)"><h2>Swipe to see more</h2><p>Tap the sides to move — try it.</p></div>
  </div>
  <button class="vst-tap vst-tap-left" id="vstPrev" aria-label="Previous story"></button>
  <button class="vst-tap vst-tap-right" id="vstNext" aria-label="Next story"></button>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Segmented top progress bars — one per slide, auto-filling over a fixed duration
Auto-advance on fill completion, exactly matching the native Instagram/Snapchat story pacing
Invisible left/right tap zones spanning the full height, plus Left/Right arrow key support
Accurate scrub state — bars for passed slides show full, upcoming ones show empty, instantly
Bars generated dynamically from slide count — add or remove a slide and the bars follow
Pure CSS width-transition timing, so the fill animation never drops frames or drifts

About this UI Snippet

Vertical Story-Style Slider — Segmented Progress Bars & Tap-to-Advance

Screenshot of the Vertical Story-Style Slider snippet rendered live

Stories replaced the carousel on every social app for one reason: the segmented bar at the top *shows you the pacing* before you even interact — how many slides remain, and roughly how much time is left on this one. This snippet rebuilds that exact mechanic from scratch: one thin bar per slide, the active one fills left-to-right over a fixed duration via a CSS width transition, and finishing a fill auto-advances to the next slide.

A CSS transition doing the timer's job

Instead of animating the fill with requestAnimationFrame on every tick, each active bar's fill gets transition: width 4000ms linear and then its width is set to 100% — the browser handles the actual animation, and a plain setTimeout matching that same duration handles advancing to the next slide. Re-visiting an already-finished slide resets its bar to full instantly (no transition), and resetting to a not-yet-reached slide snaps it back to empty — so scrubbing back and forth always shows an accurate state, not leftover animation frames.

Two invisible tap zones, not visible buttons

The left/right third of the phone frame are full-height, borderless buttons — tapping the right side advances, the left side goes back, exactly like every native stories implementation. Arrow keys do the same on desktop, so the pattern works with a keyboard too, not just a thumb.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA phone-framed story starts playing automatically — watch the first progress bar fill.
  2. 2
    Tap the right edgeAdvances to the next slide immediately and resets the timer for the new one.
  3. 3
    Tap the left edgeGoes back one slide — its bar refills from the start.
  4. 4
    Wait it outEach slide auto-advances when its bar finishes filling, just like a native story.
  5. 5
    Add a fifth slideAdd one more .vst-slide div — a matching progress bar segment is generated automatically.

Real-world uses

Common Use Cases

📣
App feature announcements
Introduce three or four new features in a story format, with segmented bars showing how many slides remain and how long this one lasts.
👋
Onboarding walkthroughs
Show new users the pacing before they interact, with bars for passed slides full and upcoming ones empty after any jump.
✨
What's new sections
Embed a story-style changelog in a marketing site, with invisible tap zones plus Left and Right arrow keys for navigation.
📂
Case study highlights
Auto-advance portfolio highlights over a fixed duration, with progress fills that finish exactly when the next slide begins.

Got questions?

Frequently Asked Questions

Change the DURATION constant (in milliseconds) at the top of the JS. It drives both the progress bar's fill transition and the setTimeout that triggers auto-advance, so they always stay in sync.

Tapping either side or pressing an arrow key immediately jumps to a slide and restarts its timer via restart() — so interacting always resets the pacing rather than fighting the running timer.

Listen for pointerdown on the phone frame and clearTimeout(timer) plus pause the active bar's fill (set its width to its current computed value and remove the transition); on pointerup, resume by re-triggering the transition for the remaining width.

Yes — .vst-slide is just a flex container; replace the background gradient with a background-image, or add an <img>/<video> as its first child sized with object-fit: cover.

Yes — Left/Right arrow keys navigate exactly like the tap zones, and the tap zones themselves are real <button> elements with aria-labels.