webdevpuneet.com

Seat-Based Pricing Calculator — Free Self-Serve Quote Widget (HTML/CSS/JS)

Seat-Based Pricing Calculator · Pricing · Plain HTML, CSS & JS · Live preview

CategoryPricing

Copy & paste

Source Code

<div class="spc-card">
  <div class="spc-head">
    <h3>Build your quote</h3>
    <p>Estimate your team's price — no sales call required</p>
  </div>

  <div class="spc-billing-toggle">
    <button type="button" class="spc-toggle-btn is-active" data-cycle="monthly">Monthly</button>
    <button type="button" class="spc-toggle-btn" data-cycle="annual">Annual <span class="spc-save-tag">Save 20%</span></button>
  </div>

  <div class="spc-seats">
    <div class="spc-seats-row">
      <label for="spcSeats">Seats</label>
      <span class="spc-seats-value" id="spcSeatsValue">12</span>
    </div>
    <div class="spc-stepper">
      <button type="button" id="spcMinus" aria-label="Decrease seats">&minus;</button>
      <input type="range" id="spcSeats" min="1" max="200" value="12" />
      <button type="button" id="spcPlus" aria-label="Increase seats">+</button>
    </div>
  </div>

  <div class="spc-breakdown">
    <div class="spc-line">
      <span>Price per seat</span>
      <b id="spcPerSeat">$15.00 <small>/mo</small></b>
    </div>
    <div class="spc-line" id="spcDiscountLine" hidden>
      <span>Annual discount (20%)</span>
      <b id="spcDiscountAmt">&minus;$36.00 <small>/mo</small></b>
    </div>
    <div class="spc-line spc-total">
      <span>Total for <span id="spcSeatCount">12</span> seats</span>
      <b id="spcTotal">$180.00 <small id="spcTotalUnit">/mo</small></b>
    </div>
    <p class="spc-billed-note" id="spcBilledNote">Billed monthly.</p>
  </div>
</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

Triple-input seat control
Slider and +/− buttons all write to one state value — never out of sync.
Visible annual discount
Shows the discount as its own line item, not a silently changed price.
Correct annualized total
Discounted monthly rate is multiplied by 12 for a true yearly total.
Effective per-seat rate
Footer note always states the true per-seat monthly price, either cycle.
Single render() function
Every number on screen derives from one small state object.
Range-clamped seats
Stepper buttons respect the slider's min/max bounds.
Formatted currency
Thousands separators and two-decimal cents throughout.
Framework-agnostic core
The pricing math is pure and ports directly to any component model.

About this UI Snippet

Seat-Based Pricing Calculator — Let Prospects Quote Their Own Team

Screenshot of the Seat-Based Pricing Calculator snippet rendered live

Per-seat SaaS pricing pages convert better when a prospect can answer "what would this cost my team" without filling out a contact form. This snippet builds that self-serve calculator in plain HTML, CSS, and vanilla JavaScript — a seat count, a monthly/annual toggle, and a live-updating total, all driven by one render() function over a tiny state object.

Seat count as a first-class control

Seats are controlled three ways at once — a range slider, and plus/minus stepper buttons — all writing to the same state.seats value and calling render(). Because every control funnels through one state object instead of maintaining its own count, the slider and the buttons can never disagree, and the displayed seat count, the line-item label, and the total all update from a single number.

Annual discount, shown as a distinct line

Rather than silently changing the per-seat price when annual billing is selected, the breakdown shows a full monthly subtotal (seats × $15) followed by a *separate* discount line at 20% off, only visible when annual is selected. This mirrors how a real pricing page should build trust — showing what the discount is worth in dollars rather than just changing a number with no explanation.

Correct monthly-vs-annual math

Monthly billing shows seats × $15 as the total, billed per month. Annual billing computes the same monthly subtotal, subtracts the 20% discount to get an effective discounted monthly rate, and then multiplies by 12 to show the true annual total — with a footer note spelling out both the effective monthly-equivalent rate and the exact per-seat price, so nothing is hidden in the switch between billing cycles. For 12 seats at $15/seat: monthly is $180.00/mo; annual is $180 × 0.8 = $144.00/mo effective, × 12 = $1,728.00/yr.

Where it fits

Drop it into a pricing page next to a pricing toggle or pricing feature table, follow it with a checkout form once a prospect is ready to buy, or pair it with a proration preview card for when an existing customer changes seat count mid-cycle.

Customizing it

Swap in your real per-seat price and discount rate, add volume-based price breaks (e.g. seats 51+ at a lower rate), or add a plan-tier selector alongside the seat count so the calculator covers your full pricing matrix.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA 12-seat monthly quote of $180.00/mo renders by default.
  2. 2
    Adjust the seat countDrag the slider or use +/− to change seats from 1 to 200.
  3. 3
    Toggle annual billingThe discount line appears and the total switches to a yearly figure.
  4. 4
    Read the effective rateThe footer note shows the discounted per-seat monthly price.
  5. 5
    Check the mathTotal always equals seats × per-seat price, minus the discount if annual.
  6. 6
    Wire up real pricingReplace PRICE_PER_SEAT_MONTHLY and ANNUAL_DISCOUNT with your live values.

Real-world uses

Common Use Cases

Self-serve SaaS quotes
Let prospects work out what a team will cost without a contact form, with a slider, plus and minus buttons all writing to one state value.
Sales-assisted deals
Give an account executive a live tool for building a quote in a call, showing the annual discount as its own visible line item.
Plan comparison pairing
Pair with a pricing card or pricing toggle, with a footer note stating the true effective per-seat monthly price.
Checkout pre-fill
Feed the chosen seat count and billing cycle into a checkout form, with the annualised total correctly multiplying the discounted monthly rate by twelve.
Mid-cycle changes and budgeting
Combine with a proration preview card when seats change mid-cycle, or let a buyer's finance team model costs at different team sizes.
Related: Plan Change Preview (Upgrade/Downgrade)
See the Plan Change Preview (Upgrade/Downgrade) for a related pricing pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

It's simply seats multiplied by the per-seat monthly price — for 12 seats at $15/seat, that's $180.00/mo. No discount applies on the monthly cycle, so the displayed per-seat price and the total always match a straightforward multiplication.

Selecting annual billing keeps the same $15/seat monthly subtotal but subtracts a 20% discount from it to get an effective discounted monthly rate ($15 × 0.8 = $12/seat), then multiplies that by 12 months for the total shown. For 12 seats, that's $144.00/mo effective × 12 = $1,728.00/yr — versus $180 × 12 = $2,160/yr at the undiscounted monthly rate, a $432/yr saving.

Showing "seats × full price" followed by an explicit "− 20% annual discount" line lets a prospect see exactly what they're saving in dollars, not just a lower number they have to trust. This transparency is what makes a self-serve calculator persuasive rather than just informative.

Not with the default slider bounds (min 1, max 200) — the +/− buttons are clamped to the same range with Math.min/Math.max, so they can never push the count outside what the slider supports. Raise the max attribute on the range input to support larger teams.

Move seats and cycle into component state (useState/ref) and derive the subtotal, discount, and total with useMemo or a computed property. Bind the slider's onChange/@input and the toggle buttons' onClick to update that state — the pricing math itself is pure and copies over unchanged.