A single Bootstrap 6 pricing card for a SaaS plan. One gradient side shows the plan name, a monthly/yearly billing toggle, a large price and a subscribe button. The white side lists what is included, with excluded features crossed out. Use it on a landing page that promotes one plan, in an upgrade dialog, or as the featured tier above a full comparison table.
How it works
The card is <article class="card card-row pcf-card"> with two .card-body panels: .pcf-plan and .pcf-features. Bootstrap 6's .card-row lays them side by side and draws the divider between them. style.css stacks the panels by default and switches to a row in an @container (min-width: 680px) rule on .pcf-root, so the card responds to its own width.
The billing switch is a .btn-group of two Bootstrap 6 toggle buttons. Each label.btn-check wraps a radio input. script.js listens for change, reads data-pcf-monthly and data-pcf-yearly from .pcf-value, and rewrites the price and the .pcf-note line. Yearly billing shows the yearly total, and monthly billing shows how much the yearly plan would save. The price block is an aria-live region, so screen readers hear the new price.
The subscribe button combines btn-solid btn-styled btn-lg theme-inverse with custom --bs-theme-bg and --bs-theme-contrast values, which gives a white button with rose text on the gradient. On click it shows a .spinner-border.spinner-sm and a busy label. After a simulated request it adds .pcf-cta--done, which turns the button green, and updates the .pcf-fine status line. Picking another billing period resets the demo.
Customization
--pcf-fromand--pcf-toon.pcf-root: set the two gradient colors of the plan panel (and the button text and link color).--pcf-checkon.pcf-root: changes the color of the included-feature check icons.--pcf-plan-widthon.pcf-root: sets how wide the plan panel is in the side-by-side layout (46% by default).data-pcf-monthlyanddata-pcf-yearlyon.pcf-value: your per-user prices. The note and savings are calculated from them.- Add
.pcf-item--offto any.pcf-itemto show it as not included (gray, struck through, with a hidden "Not included" label). - Replace the
setTimeoutin the.pcf-ctaclick handler with your checkout call. The currentbillingvalue is available there. - Change the
680pxin the@containerrule to control when the panels sit side by side.
Use cases
- Landing pages: promote one plan with a large price and a feature checklist
- Upgrade dialogs: a monthly or yearly toggle changes the price shown
- Pricing pages: use it as the featured tier above a full comparison table
- SaaS signups: excluded features are crossed out, and the subscribe button shows a loading state
Accessibility
The billing options are native radio inputs in a labelled role="group", so arrow keys work. Price changes are announced through aria-live, and the result of the subscribe action is announced through the role="status" line. Excluded features carry visually hidden "Not included:" text, so their meaning does not depend on the strikethrough. All icons are aria-hidden, and every control has a visible focus outline.
Bootstrap 6 notes
btn-primary becomes btn-solid theme-*, and .btn-styled adds the gradient sheen. Toggle buttons wrap their input in label.btn-check. spinner-border-sm is now spinner-sm, and horizontal cards use .card-row instead of a grid inside the card. Built on Bootstrap 6.0.0-alpha.1, so APIs may still change. Icons come from Bootstrap Icons.