Split-Panel Comparison Carousel — HTML CSS JS Snippet

Split-Panel Comparison Carousel · Cards · Plain HTML, CSS & JS · Live preview

What's included

Features

One shared index drives two independent slide tracks — they can never show mismatched tiers
Both columns advance in perfect lockstep on every navigation action
Direction-aware slide transitions — outgoing and incoming slides move opposite ways, not a flat crossfade
Auto-generated position dots let a visitor jump straight to a specific comparison tier
Prev/next buttons labeled for their actual purpose ("Compare higher tier") rather than generic arrows
Fully keyboard operable via Left/Right arrow keys

About this UI Snippet

Split-Panel Comparison Carousel — Two Tracks, One Shared Index

Screenshot of the Split-Panel Comparison Carousel snippet rendered live

A visitor comparing two things — two pricing plans, two products, two time periods — usually has to page each carousel separately and hold the other one in their head. This snippet removes that step: a *single* current index drives two independent slide tracks at once, so clicking "next" once advances both columns to their matching tier simultaneously. Comparing "Growth" against "Pro" is never more than one click away from comparing "Starter" against "Basic."

One render function, two tracks

render() loops over [slidesA, slidesB] and applies the exact same active/previous logic to both groups from the one current value — there's no risk of the two columns ever showing mismatched tiers, because there's only one variable deciding what "current" means for either of them.

Direction-aware exit, not just enter

Each slide tracks not just whether it's active, but whether it was the *previous* active slide (spc-prev), so the outgoing card can be given a distinct exit transform (translateX(-100%)) instead of just disappearing — while the incoming one enters from the opposite side (translateX(100%)0). That's what makes the transition read as "sliding to the next tier" rather than a flat crossfade.

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 why render() loops over an array of both slide groups instead of writing the active/previous logic twice — and what bug class that refactor prevents as more comparison columns get added later. It's also worth asking the assistant to add a "highlight the difference" feature that visually flags which line items differ between the two currently-visible tiers, or to make the whole thing swipeable for mobile.

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 two-column comparison carousel in plain HTML, CSS, and vanilla JavaScript where both columns page through their own set of slides in perfect lockstep, driven by a single shared index — no library.

Requirements:
- Two side-by-side columns, each containing its own stack of absolutely-positioned slide cards (e.g. pricing tiers), where within each column only one slide is visible at a time via CSS transforms and transitions.
- Exactly one shared "current index" JavaScript variable controls which slide is active in BOTH columns simultaneously — there must be no way for the two columns to independently show slides at different index positions from each other.
- A single render function that loops over both columns' slide groups and applies the same active-state logic to each, rather than duplicating that logic once per column.
- Each slide must track two states, not just one: whether it is the currently active slide, and whether it was the previously active slide — so an outgoing slide can transform off in one direction (e.g. slide left and fade) while the newly active slide enters from the opposite direction, producing a genuine directional slide transition rather than an abrupt swap.
- Previous/next buttons (labeled for their actual comparison purpose, not generic arrows) that step the shared index within bounds, plus a row of dynamically generated indicator dots where clicking a dot jumps the shared index directly to that position.
- Left/Right arrow key support performing the same next/previous action as the buttons.

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="spc-wrap">
  <div class="spc-cols">
    <div class="spc-col">
      <div class="spc-badge spc-badge-a">Plan A</div>
      <div class="spc-track" id="spcTrackA">
        <div class="spc-slide"><h3>Starter</h3><div class="spc-price">$9<span>/mo</span></div><ul><li>5 projects</li><li>2 GB storage</li><li>Community support</li></ul></div>
        <div class="spc-slide"><h3>Growth</h3><div class="spc-price">$29<span>/mo</span></div><ul><li>25 projects</li><li>20 GB storage</li><li>Email support</li></ul></div>
        <div class="spc-slide"><h3>Scale</h3><div class="spc-price">$79<span>/mo</span></div><ul><li>Unlimited projects</li><li>200 GB storage</li><li>Priority support</li></ul></div>
      </div>
    </div>
    <div class="spc-col">
      <div class="spc-badge spc-badge-b">Plan B</div>
      <div class="spc-track" id="spcTrackB">
        <div class="spc-slide"><h3>Basic</h3><div class="spc-price">$12<span>/mo</span></div><ul><li>3 projects</li><li>1 GB storage</li><li>Forum support</li></ul></div>
        <div class="spc-slide"><h3>Pro</h3><div class="spc-price">$34<span>/mo</span></div><ul><li>15 projects</li><li>15 GB storage</li><li>Chat support</li></ul></div>
        <div class="spc-slide"><h3>Business</h3><div class="spc-price">$99<span>/mo</span></div><ul><li>Unlimited projects</li><li>500 GB storage</li><li>24/7 phone support</li></ul></div>
      </div>
    </div>
  </div>
  <div class="spc-controls">
    <button class="spc-btn" id="spcPrev" aria-label="Previous tier">‹ Compare lower tier</button>
    <div class="spc-dots" id="spcDots"></div>
    <button class="spc-btn" id="spcNext" aria-label="Next tier">Compare higher tier ›</button>
  </div>
</div>

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSTwo pricing columns appear side by side, both showing their entry-level tier.
  2. 2
    Click "Compare higher tier"Both columns slide to their next tier at the exact same moment.
  3. 3
    Click a dotJump both columns directly to a specific tier level in one click.
  4. 4
    Use arrow keysLeft/Right pages both tracks together without touching the buttons.
  5. 5
    Adapt the contentSwap in product specs, feature sets, or any two things worth comparing tier-by-tier.

Real-world uses

Common Use Cases

Side-by-side pricing comparisons
Compare your plan tiers against a competitor's at matching levels, one click apart.
Product or spec comparisons
Page two product lines' specs in sync — camera A vs camera B, model by model.
Before/after or period comparisons
Compare quarterly metrics or before/after states across a synced timeline.
Feature-by-feature vendor comparisons
Walk a visitor through your offering against an alternative at every tier without them losing their place.

Got questions?

Frequently Asked Questions

Yes — add a third .spc-col with its own track and slide set, and include it in the [slidesA, slidesB] array in render() (renamed to include the third group) so all three advance together.

Keep them equal — next()/prev() bound their range using slidesA.length, so a shorter track B would run out of matching slides before track A. Pad the shorter one with a placeholder or empty tier if needed.

Attach a touchstart/touchend listener to .spc-cols, and call next()/prev() based on the horizontal drag delta — since both tracks share one render() call, a single swipe handler is enough to move both.

That would defeat the comparison purpose of this pattern — for independent tracks, use two separate plain Carousel snippets instead; this one is specifically built around one shared index.

Yes — the buttons carry descriptive aria-labels, dots are individually labeled by tier, and the whole comparison is operable via Left/Right arrow keys.