Good fit for
- Subscription pricing
- Membership plans
- SaaS comparison pages
This billing controls pattern works best when its purpose is clear in the surrounding page hierarchy.
Open experiment
A compact monthly and annual billing selector with explicit savings copy, pressed state, live price updates, and keyboard-ready native buttons.
<section class="cmp-billing-period-toggle" data-period="monthly">
<header><span>Billing period</span><strong>Save 20% annually</strong></header>
<div class="cmp-billing-period-toggle__switch" role="group" aria-label="Choose billing period">
<button type="button" data-period="monthly" aria-pressed="true">Monthly</button>
<button type="button" data-period="annual" aria-pressed="false">Annual</button>
</div>
<div class="cmp-billing-period-toggle__price">
<span>Team plan</span>
<p>
<strong data-price data-monthly="24" data-annual="19">$24</strong
><small data-suffix>/month</small>
</p>
</div>
<p class="cmp-billing-period-toggle__status" data-status aria-live="polite">
Monthly billing selected.
</p>
</section>
Validated in the lab
License: MIT License for open-source use, modification, and distribution.
Implementation field notes
The preview and source are only the starting point. Use these notes to decide where the component fits, preserve its accessibility contract, and verify the adapted result.
This billing controls pattern works best when its purpose is clear in the surrounding page hierarchy.
Related learning