Home / Snippets / Layout /

Pricing card with CQ

Pricing card that adapts layout via container queries — no media queries needed.

Starter
$9/mo
5 projects
10GB storage
Email support
Enterprise
$99/mo
Everything in Pro
Unlimited storage
Dedicated support
Custom integrations
Widely supported
layoutno-js

Quick implementation

/* HTML: 
<div class="pricing-wrapper">
  <div class="pricing-card">
    <div class="pricing-header">
      <div class="plan-name">Pro</div>
      <div class="price">$29</div>
    </div>
    <div class="pricing-features">...</div>
    <div class="pricing-cta"><button>Get started</button></div>
  </div>
</div>
*/

.pricing-wrapper {
  container-type: inline-size;
  container-name: pricing;
}

.pricing-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.5rem;
  border: 1px solid var(--card-border);
  border-radius: var(--radius);
  background: var(--card);
}

.pricing-header {
  text-align: center;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--card-border);
}

.pricing-features {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.pricing-cta {
  border-top: 1px solid var(--card-border);
  padding-top: 1rem;
}

/* Wide layout (container >= 18rem) */
@container pricing (min-width: 18rem) {
  .pricing-card {
    flex-direction: row;
    align-items: stretch;
  }
  .pricing-header {
    flex: 0 0 8rem;
    text-align: left;
    border-bottom: none;
    border-right: 1px solid var(--card-border);
  }
  .pricing-features {
    flex: 1;
    border-right: 1px solid var(--card-border);
  }
  .pricing-cta {
    flex: 0 0 8rem;
    border-top: none;
    border-left: 1px solid var(--card-border);
  }
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer specializing in modern CSS layout.

Goal: Build a pricing card component that adapts its layout based on available container width — no JavaScript.

Technical constraints:
- Use container-type: inline-size and @container queries to detect wrapper width.
- Structure: header (plan name + price) + features list + CTA button.
- Use oklch() for all colors — no hex or rgba().
- Layout shift: horizontal (side-by-side sections) when wide, vertical (stacked) when narrow.
- Include focus-visible styles for interactive elements (buttons, links).

Framework variant (pick one):
A) Vanilla HTML + CSS only.
B) React component — accept `plan`, `price`, `period`, `features` (array), `onCtaClick` props; include CSS as a CSS module.

Edge cases to handle:
- Popular/featured variant with accent border and badge.
- What happens if container queries are not supported? Provide a media query fallback.
- ARIA: use semantic elements (<article> for card, <h3> for plan name) and aria-label on the wrapper.

Why this matters in 2026

Pricing pages traditionally rely on fixed-width columns or media queries that break when you reuse cards in different contexts. Container queries let each pricing card self-adapt to its wrapper — stacked in a narrow sidebar, horizontal in a wide pricing section. The same component works everywhere without modifier classes.

This is component-driven design at its best: the card knows its constraints and styles accordingly. No more passing width props or maintaining separate mobile/desktop variants.

The logic

container-type: inline-size on the wrapper establishes a sizing context. The @container pricing (min-width: 18rem) rule switches the card from flex-direction: column to row when space allows. Sections get fixed flex-basis values (flex: 0 0 8rem) to create balanced columns.

Why 18rem? It's the minimum width where side-by-side sections remain readable. Below that, stacking preserves vertical rhythm. Tune the breakpoint based on your content's actual minimums.

Accessibility & performance

Container queries are pure CSS — no performance cost. For accessibility, wrap cards in <article> and use proper heading hierarchy (<h3> for plan names). Buttons must have visible focus rings. The popular badge should be decorative only — don't rely on color alone to distinguish plans; use text labels too.

Browser support: Container queries landed in all major browsers in 2023. For older browsers, provide a @media (min-width: 18rem) fallback that defaults to the wide layout.