Pricing Card
FreeA structured card presenting a plan name, price, feature list, and call-to-action button. Supports a "popular" badge to highlight the recommended tier. Used on pricing pages to let users compare and select plans at a glance.
6 variants
Variants
| Variant | Description | When to use |
|---|---|---|
| Default | Standard pricing card with plan name, price, features, and CTA. | Use for each plan tier on a pricing page. |
| Featured | ||
| Compact |
Usage Guidelines
Do
Use heading hierarchy (h3 for plan name) so screen readers can navigate between cards.
Don't
Mark more than one card as "Popular" — it defeats the purpose.
Do
Highlight the recommended plan with the Popular variant and badge.
Don't
Hide pricing details behind hover states or tooltips.
Do
List features with checkmarks for included and muted text for excluded.
Don't
Use inconsistent feature ordering across cards — align rows for easy comparison.
Do
Make the CTA button text specific — "Start Free Trial" not just "Select".
Don't
Code
HTML
<div class="lex-pricing-card lex-pricing-card--popular">
<span class="lex-pricing-card__badge">Most Popular</span>
<h3 class="lex-pricing-card__plan">Pro</h3>
<div class="lex-pricing-card__price">
<span class="lex-pricing-card__amount">$29</span>
<span class="lex-pricing-card__period">/month</span>
</div>
<ul class="lex-pricing-card__features" role="list">
<li class="lex-pricing-card__feature lex-pricing-card__feature--included">
<svg aria-hidden="true" class="lex-pricing-card__check"><!-- check --></svg>
Unlimited projects
</li>
<li class="lex-pricing-card__feature lex-pricing-card__feature--included">
<svg aria-hidden="true" class="lex-pricing-card__check"><!-- check --></svg>
Priority support
</li>
<li class="lex-pricing-card__feature lex-pricing-card__feature--excluded">
<svg aria-hidden="true" class="lex-pricing-card__x"><!-- x --></svg>
Custom domain
</li>
</ul>
<button class="lex-button lex-button--primary lex-button--md">
Start Free Trial
</button>
</div>CSS Custom Properties
.lex-pricing-card {
background: var(--lex-pricing-card-bg);
border: 1px solid var(--lex-pricing-card-border);
border-radius: var(--lex-pricing-card-radius, var(--lex-radius-xl));
padding: var(--lex-space-32);
display: flex;
flex-direction: column;
gap: var(--lex-space-24);
position: relative;
}
.lex-pricing-card--popular {
border-color: var(--lex-pricing-card-popular-border);
box-shadow: var(--lex-pricing-card-popular-shadow, var(--lex-shadow-lg));
}
.lex-pricing-card__badge {
position: absolute;
top: calc(-1 * var(--lex-space-12));
left: 50%;
transform: translateX(-50%);
background: var(--lex-pricing-card-badge-bg);
color: var(--lex-pricing-card-badge-text);
padding: var(--lex-space-4) var(--lex-space-12);
border-radius: var(--lex-radius-pill);
font-size: var(--lex-font-size-xs);
font-weight: 600;
}
.lex-pricing-card__amount {
font-size: var(--lex-pricing-card-price-size, var(--lex-font-size-4xl));
font-weight: 700;
color: var(--lex-pricing-card-price-color, var(--lex-text-primary));
}
.lex-pricing-card__period {
color: var(--lex-text-muted);
font-size: var(--lex-font-size-sm);
}
.lex-pricing-card__features {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: var(--lex-space-8);
}
.lex-pricing-card__feature--excluded {
color: var(--lex-text-muted);
text-decoration: line-through;
}React
// Using Lexicon CSS classes with React
export function ProPlan() {
return (
<PricingCard
plan="Pro"
price={29}
period="month"
badge="Most Popular"
popular
cta="Start Free Trial"
onCtaClick={() => startTrial('pro')}
>
<PricingFeature included>Unlimited projects</PricingFeature>
<PricingFeature included>Priority support</PricingFeature>
<PricingFeature>Custom domain</PricingFeature>
</PricingCard>
);
}Design Tokens
| Token | Value (dark) | Value (light) | CSS property |
|---|---|---|---|
| --lex-card-bg | — | — | bg |
| --lex-card-border | — | — | border |
| --lex-card-radius | — | — | radius |
| --lex-card-padding | — | — | padding |
| --lex-pricing-featured-border | — | — | border |
Accessibility
- Use h3 (or appropriate heading level) for the plan name to support screen-reader navigation.
- Feature list uses role="list" so assistive tech announces the item count.
- Included/excluded features are distinguished by text, not colour alone — use checkmark/x icons with aria-hidden and descriptive text.
- CTA button text should be descriptive — "Start Free Trial" rather than "Select".
- Popular badge is purely visual emphasis; the card content communicates the plan details.