webdevpuneet.com

Pricing Slider — Per-Seat Price Slider HTML CSS JS

Pricing Slider · Pricing · Plain HTML, CSS & JS · Live preview

CategoryPricing

Copy & paste

Source Code

<div class="ps-card">
  <div class="ps-plan" id="psPlan"></div>
  <div class="ps-head">
    <h3 id="psName"></h3>
    <p class="ps-seats"><b id="psSeats"></b> team members</p>
  </div>
  <input type="range" id="psRange" class="ps-range" min="1" max="100" value="8">
  <div class="ps-ticks"><span>1</span><span>25</span><span>50</span><span>75</span><span>100</span></div>
  <div class="ps-price">
    <span class="ps-amt" id="psAmt"></span>
    <span class="ps-per">/ month</span>
  </div>
  <p class="ps-note" id="psNote"></p>
  <button type="button" class="ps-cta" id="psCta"></button>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), 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

Tiered volume pricing
A TIERS table gives bigger teams lower per-seat rates, like real SaaS pricing.
Plan changes with size
Name, accent, badge, note, and CTA all update as you cross tiers.
Live total
The price recomputes on every drag — answering "what will this cost me?".
Colour-filled track
A gradient fills the slider up to the thumb in the tier's colour.
Custom cross-browser thumb
Styled via ::-webkit-slider-thumb and ::-moz-range-thumb.
Top-tier handoff
The largest tier flips the CTA to Contact sales.
Single source of truth
Everything derives from the current tier for consistency.
Data-driven & no library
Edit the TIERS table to reprice — plain HTML/CSS/JS, zero dependencies.

About this UI Snippet

Pricing Slider — Drag Team Size to See the Plan, Per-Seat Rate, and Total

Screenshot of the Pricing Slider snippet rendered live

A pricing slider lets a prospect drag to their team size (or usage) and instantly see what they'd pay — turning a static pricing table into an interactive, personalised quote. This snippet builds it in plain HTML, CSS, and vanilla JavaScript, with tiered per-seat pricing, a plan name and accent colour that change with size, and a slider track that fills as you drag — no library.

Tiered, volume-based pricing

The pricing isn't flat: bigger teams get a lower per-seat rate, defined by a TIERS table (up to 5 seats → $12/seat Starter, up to 20 → $10 Team, and so on). tierFor(seats) finds the tier the current size falls into, and the total is seats × that tier's rate. Encoding volume discounts as a tier table — rather than a formula — makes the pricing easy to read, change, and match to your real plans, and it's how most SaaS per-seat pricing actually works.

The plan changes as you drag

Crossing a tier boundary doesn't just change the rate — the plan name, the accent colour, the badge, the note, and even the CTA all update (the top tier flips the button to "Contact sales"). Reflecting the whole plan identity from the slider position makes the interaction feel like exploring real plans, not just watching a number tick. Everything derives from the current tier, so it stays consistent.

A filled slider track

The native range input's track is filled up to the thumb with the tier's colour using a linear-gradient whose stop is the slider's percentage — recomputed on every input. This gives the standard "progress-filled" slider look (which native inputs don't provide) and ties the fill colour to the current tier, so the control itself reinforces which plan you're in. Custom thumb styling via ::-webkit-slider-thumb and ::-moz-range-thumb keeps it on-brand across browsers.

Live total, instantly

Dragging recomputes the seats, tier, per-seat rate, and total on every input event, so the big price updates in real time. Showing the live total (with the per-seat breakdown beneath) answers the prospect's actual question — "what will this cost *me*?" — far more effectively than a grid of fixed numbers, which research links to higher pricing-page conversion.

Data-driven and drop-in

Edit the TIERS table to match your plans and rates, change the slider range to your seat or usage limits, and wire the CTA to checkout with the current seat count. It's a clear reference for tiered pricing logic, a colour-filled range input, and slider-driven plan selection. A native <input type="range"> is also keyboard- and screen-reader-friendly out of the box — arrow keys nudge the value and the accessible name comes from a label — which a custom drag-to-position div slider would have to reimplement, so it's worth keeping the real range element even after the heavy visual restyling applied here.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA pricing card renders with a team-size slider and a live total.
  2. 2
    Drag the sliderAs you change team size, the plan, per-seat rate, total, and accent update live.
  3. 3
    Cross a tierPassing a tier boundary changes the plan name, colour, and CTA (top tier → Contact sales).
  4. 4
    Edit the tiersChange the TIERS table to your plans, seat caps, and per-seat rates.
  5. 5
    Set the rangeAdjust the slider min/max to your seat or usage limits.
  6. 6
    Wire checkoutSend the current seat count to your checkout from the CTA handler.

Real-world uses

Common Use Cases

SaaS per-seat pricing
Let teams find their price by size — pair with a pricing page for plan details.
Usage-based pricing
Slide usage (API calls, storage) to a cost, alongside a usage calculator for multi-input estimates.
Plan recommendation
Guide prospects to the right tier from a single slider, next to a plan selector.
Quote and estimate widgets
Interactive quotes on a landing page.
Upgrade prompts
Show the cost of adding seats in-app.
Learning tiered pricing logic
A reference for tier lookups and filled range inputs — compare with a pricing toggle.
Related: Transparent Fees Breakdown
See the Transparent Fees Breakdown for a related pricing pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

A TIERS table lists, for each tier, the maximum seats it covers and the per-seat rate (smaller for bigger teams). tierFor(seats) returns the first tier whose upTo is at least the current seat count, and the total is seats × that tier's per-seat rate. Using a table rather than a formula makes volume discounts easy to read and to match to your real published plans.

Native range inputs don't show a filled portion by default. The snippet sets the input's background to a linear-gradient with a hard stop at the current value's percentage — coloured up to the thumb, grey after — and recomputes that percentage on every input event. The stop colour is the current tier's accent, so the fill also signals which plan you're in. Custom thumb styling makes it consistent across browsers.

Updating the plan name, accent colour, badge, note, and CTA as the slider crosses tiers makes the interaction feel like exploring your actual plans, not just scrubbing a price. It connects the cost to a named plan with its own identity, which is more persuasive and informative than a bare number — and it sets up the top-tier "Contact sales" handoff for enterprise.

Read the current seat count (range.value) and tier in the CTA's click handler, then pass them to your checkout — e.g. redirect to Stripe with the right price ID and quantity, or open your signup with the seat count prefilled. For the top tier, route to a contact-sales form instead. The slider is the configurator; your checkout consumes its output.

Hold the seat count in state, derive the tier and total with a computed/useMemo, and bind them to the display and the slider's fill style. In React use useState with an onChange; in Vue v-model with computed; in Angular ngModel with a getter. The TIERS lookup and pricing math are framework-agnostic — only the state and bindings move into the framework.