21 CSS Pricing Sections01 / 21

Pure CSSMIT licensed

Classic Three Tier

The canonical SaaS pricing layout — three equal tier cards (Starter / Team / Business) with emerald accent. Real <ul> feature lists, dashed dividers, and full-width CTAs at the bottom. The conversion-tested baseline every team starts from.

Published

Live Demo
Try it

The code

<section class="ps-01" aria-label="Pricing">
  <header class="ps-01__head">
    <span class="ps-01__eye">Pricing</span>
    <h2>Pick the plan that fits today.</h2>
    <p>Upgrade, downgrade, or cancel any time. No fine print.</p>
  </header>
  <div class="ps-01__grid">
    <article class="ps-01__card">
      <h3>Starter</h3>
      <p class="ps-01__sub">For solo builders shipping their first thing.</p>
      <div class="ps-01__price">
        <span class="ps-01__amt">$9</span><span class="ps-01__per">/ month</span>
      </div>
      <ul class="ps-01__feats">
        <li>1 project</li>
        <li>2 GB storage</li>
        <li>Community support</li>
        <li>Basic analytics</li>
      </ul>
      <a class="ps-01__cta" href="#starter">Start free →</a>
    </article>
    <article class="ps-01__card">
      <h3>Team</h3>
      <p class="ps-01__sub">For small teams who need to ship together.</p>
      <div class="ps-01__price">
        <span class="ps-01__amt">$29</span><span class="ps-01__per">/ month</span>
      </div>
      <ul class="ps-01__feats">
        <li>10 projects</li>
        <li>50 GB storage</li>
        <li>Email support</li>
        <li>Team analytics</li>
        <li>Role-based access</li>
      </ul>
      <a class="ps-01__cta" href="#team">Start 14-day trial →</a>
    </article>
    <article class="ps-01__card">
      <h3>Business</h3>
      <p class="ps-01__sub">For growing companies that need governance.</p>
      <div class="ps-01__price">
        <span class="ps-01__amt">$79</span><span class="ps-01__per">/ month</span>
      </div>
      <ul class="ps-01__feats">
        <li>Unlimited projects</li>
        <li>500 GB storage</li>
        <li>Priority support</li>
        <li>Advanced analytics</li>
        <li>SSO + audit logs</li>
        <li>SOC 2 ready</li>
      </ul>
      <a class="ps-01__cta" href="#business">Talk to sales →</a>
    </article>
  </div>
</section>
.ps-01 {
  display: block;
  padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
  width: 100%;
  min-height: 100vh;
  background: #07120e;
  color: #e7f5ee;
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
}

.ps-01__head {
  text-align: center;
  margin-bottom: clamp(20px, 4vw, 40px);
}

.ps-01__eye {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #34d399;
  margin-bottom: 12px;
}

.ps-01__head h2 {
  font-size: clamp(22px, 3.4vw, 34px);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
}

.ps-01__head p {
  color: #9bb5a8;
  margin: 0;
  font-size: 14px;
}

.ps-01__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  max-width: 980px;
  margin: 0 auto;
}

.ps-01__card {
  background: #0d1f18;
  border: 1px solid rgba(52,211,153,0.2);
  border-radius: 14px;
  padding: 22px 20px 20px;
  display: flex;
  flex-direction: column;
  transition: border-color 0.2s, transform 0.2s;
}

.ps-01__card:hover {
  border-color: #34d399;
  transform: translateY(-2px);
}

.ps-01__card h3 {
  font-size: 15px;
  font-weight: 700;
  margin: 0 0 4px;
  color: #34d399;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.ps-01__sub {
  font-size: 13px;
  color: #9bb5a8;
  margin: 0 0 18px;
  line-height: 1.5;
  min-height: 38px;
}

.ps-01__price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 18px;
  padding-bottom: 18px;
  border-bottom: 1px dashed rgba(52,211,153,0.25);
}

.ps-01__amt {
  font-size: 38px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: #f0fff7;
}

.ps-01__per {
  font-size: 13px;
  color: #9bb5a8;
}

.ps-01__feats {
  list-style: none;
  padding: 0;
  margin: 0 0 22px;
  flex: 1;
}

.ps-01__feats li {
  position: relative;
  padding: 6px 0 6px 22px;
  font-size: 13.5px;
  color: #d2e9dc;
}

.ps-01__feats li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 14px;
  height: 14px;
  transform: translateY(-50%);
  background: linear-gradient(135deg, transparent 50%, #34d399 50%) center/100% 100% no-repeat;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
  background: #34d399;
}

.ps-01__cta {
  display: block;
  text-align: center;
  padding: 11px 16px;
  border-radius: 8px;
  background: rgba(52,211,153,0.12);
  color: #34d399;
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 600;
  border: 1px solid rgba(52,211,153,0.28);
  transition: background 0.18s, color 0.18s;
}

.ps-01__cta:hover {
  background: #34d399;
  color: #07120e;
}

.ps-01__cta:focus-visible {
  outline: 2px solid #34d399;
  outline-offset: 3px;
}

@media (max-width: 820px) {
  .ps-01__grid {
    grid-template-columns: 1fr;
    max-width: 460px;
  }

  .ps-01__sub {
    min-height: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ps-01__card {
    transition: none;
  }

  .ps-01__card:hover {
    transform: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Pricing Section from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Classic Three Tier
Source: https://codefronts.com/layouts/css-pricing-sections/classic-three-tier/

The canonical SaaS pricing layout — three equal tier cards (Starter / Team / Business) with emerald accent. Real <ul> feature lists, dashed dividers, and full-width CTAs at the bottom. The conversion-tested baseline every team starts from.
## HTML
```html
<section class="ps-01" aria-label="Pricing">
  <header class="ps-01__head">
    <span class="ps-01__eye">Pricing</span>
    <h2>Pick the plan that fits today.</h2>
    <p>Upgrade, downgrade, or cancel any time. No fine print.</p>
  </header>
  <div class="ps-01__grid">
    <article class="ps-01__card">
      <h3>Starter</h3>
      <p class="ps-01__sub">For solo builders shipping their first thing.</p>
      <div class="ps-01__price">
        <span class="ps-01__amt">$9</span><span class="ps-01__per">/ month</span>
      </div>
      <ul class="ps-01__feats">
        <li>1 project</li>
        <li>2 GB storage</li>
        <li>Community support</li>
        <li>Basic analytics</li>
      </ul>
      <a class="ps-01__cta" href="#starter">Start free →</a>
    </article>
    <article class="ps-01__card">
      <h3>Team</h3>
      <p class="ps-01__sub">For small teams who need to ship together.</p>
      <div class="ps-01__price">
        <span class="ps-01__amt">$29</span><span class="ps-01__per">/ month</span>
      </div>
      <ul class="ps-01__feats">
        <li>10 projects</li>
        <li>50 GB storage</li>
        <li>Email support</li>
        <li>Team analytics</li>
        <li>Role-based access</li>
      </ul>
      <a class="ps-01__cta" href="#team">Start 14-day trial →</a>
    </article>
    <article class="ps-01__card">
      <h3>Business</h3>
      <p class="ps-01__sub">For growing companies that need governance.</p>
      <div class="ps-01__price">
        <span class="ps-01__amt">$79</span><span class="ps-01__per">/ month</span>
      </div>
      <ul class="ps-01__feats">
        <li>Unlimited projects</li>
        <li>500 GB storage</li>
        <li>Priority support</li>
        <li>Advanced analytics</li>
        <li>SSO + audit logs</li>
        <li>SOC 2 ready</li>
      </ul>
      <a class="ps-01__cta" href="#business">Talk to sales →</a>
    </article>
  </div>
</section>
```
## CSS
```css
.ps-01 {
  display: block;
  padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
  width: 100%;
  min-height: 100vh;
  background: #07120e;
  color: #e7f5ee;
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
}

.ps-01__head {
  text-align: center;
  margin-bottom: clamp(20px, 4vw, 40px);
}

.ps-01__eye {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #34d399;
  margin-bottom: 12px;
}

.ps-01__head h2 {
  font-size: clamp(22px, 3.4vw, 34px);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
}

.ps-01__head p {
  color: #9bb5a8;
  margin: 0;
  font-size: 14px;
}

.ps-01__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  max-width: 980px;
  margin: 0 auto;
}

.ps-01__card {
  background: #0d1f18;
  border: 1px solid rgba(52,211,153,0.2);
  border-radius: 14px;
  padding: 22px 20px 20px;
  display: flex;
  flex-direction: column;
  transition: border-color 0.2s, transform 0.2s;
}

.ps-01__card:hover {
  border-color: #34d399;
  transform: translateY(-2px);
}

.ps-01__card h3 {
  font-size: 15px;
  font-weight: 700;
  margin: 0 0 4px;
  color: #34d399;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.ps-01__sub {
  font-size: 13px;
  color: #9bb5a8;
  margin: 0 0 18px;
  line-height: 1.5;
  min-height: 38px;
}

.ps-01__price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 18px;
  padding-bottom: 18px;
  border-bottom: 1px dashed rgba(52,211,153,0.25);
}

.ps-01__amt {
  font-size: 38px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: #f0fff7;
}

.ps-01__per {
  font-size: 13px;
  color: #9bb5a8;
}

.ps-01__feats {
  list-style: none;
  padding: 0;
  margin: 0 0 22px;
  flex: 1;
}

.ps-01__feats li {
  position: relative;
  padding: 6px 0 6px 22px;
  font-size: 13.5px;
  color: #d2e9dc;
}

.ps-01__feats li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 14px;
  height: 14px;
  transform: translateY(-50%);
  background: linear-gradient(135deg, transparent 50%, #34d399 50%) center/100% 100% no-repeat;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M6.5 11.5 3 8l1-1 2.5 2.5L12 4l1 1z'/></svg>") center/contain no-repeat;
  background: #34d399;
}

.ps-01__cta {
  display: block;
  text-align: center;
  padding: 11px 16px;
  border-radius: 8px;
  background: rgba(52,211,153,0.12);
  color: #34d399;
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 600;
  border: 1px solid rgba(52,211,153,0.28);
  transition: background 0.18s, color 0.18s;
}

.ps-01__cta:hover {
  background: #34d399;
  color: #07120e;
}

.ps-01__cta:focus-visible {
  outline: 2px solid #34d399;
  outline-offset: 3px;
}

@media (max-width: 820px) {
  .ps-01__grid {
    grid-template-columns: 1fr;
    max-width: 460px;
  }

  .ps-01__sub {
    min-height: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ps-01__card {
    transition: none;
  }

  .ps-01__card:hover {
    transform: none;
  }
}
```

How this works

The layout is a semantic <section> wrapping a centered .ps-01__head plus .ps-01__grid using display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) with gap: 16px — the canonical anchor-and-recommend layout for any SaaS pricing page. The minmax(0, 1fr) is load-bearing: without the 0 minimum, long feature strings force intrinsic column widths and one tier bulges wider than the other two, breaking the visual parity that the three-column tier design depends on. Each .ps-01__card is display: flex; flex-direction: column so flex: 1 on the feature list glues every CTA to the card bottom regardless of feature-count skew (4 items in Starter, 6 in Business).

The palette is a deep forest #07120e base with body text #e7f5ee and a single emerald accent #34d399 that carries eyebrow, tier titles, price emphasis, and the check-mark icon painted via a masked SVG — one color, four jobs, zero paint cost. The Inter typeface with letter-spacing: -0.01em on the h2 and letter-spacing: 0.18em; text-transform: uppercase on the eyebrow is the standard fintech / developer-tools trust signal. The dashed border-bottom: 1px dashed rgba(52,211,153,0.25) under each price separates commitment (the number) from proof (the feature list) — a subtle Baymard-validated grouping cue.

Why it converts: the three-tier pricing card layout is the anchor-effect execution — Starter at $9 sets the floor, Business at $79 sets the ceiling, and the eye lands on Team at $29 as the mid-anchor. Iyengar & Lepper's jam-shelf work shows three options maximize conversion versus one or six; three tiers hits that sweet spot exactly. Every CTA gets :focus-visible with a 2px emerald ring at outline-offset: 3px, and the hover only shifts transform: translateY(-2px) + border-color — compositor-only, so INP on the card interaction stays well under 200ms even on mid-tier Android.

Make it yours

  • Recolor the emerald: change #34d399 (accent) and #e7f5ee (body) to your brand. Keep the accent above 4.5:1 against #07120e for WCAG 1.4.3 AA on the CTA text — Tailwind's emerald-400, sky-400, and violet-400 all clear that bar against a near-black surface.
  • Swap Inter for the register you want: 'IBM Plex Sans' for developer tools, 'Söhne' or 'General Sans' for premium B2B SaaS, 'Manrope' for startup pricing card energy. Keep letter-spacing: -0.01em on the h2 — every geometric sans needs it to avoid feeling airy at display sizes.
  • Change the CTA shape from border-radius: 8px to border-radius: 999px for a pill CTA (fintech default) or border-radius: 0 for a brutalist / developer-tools look. The rgba(52,211,153,0.12) ghost fill can drop to transparent if you want the CTA to read as a link on the two side tiers and reserved solid emerald for a highlighted Team card.
  • For a light-mode inversion: swap #07120e#f5faf7, #e7f5ee#0d1f18, keep #34d399 as accent, but bump the card border to rgba(15,118,72,0.28) and the dashed divider to rgba(15,118,72,0.35) — the original 0.2–0.25 alphas disappear on cream.
  • Tailwind mapping: section bg-[#07120e] text-[#e7f5ee] font-sans, grid grid grid-cols-1 md:grid-cols-3 gap-4 max-w-[980px] mx-auto, card bg-[#0d1f18] border border-emerald-400/20 rounded-2xl p-6 flex flex-col hover:border-emerald-400 hover:-translate-y-0.5 transition, CTA bg-emerald-400/10 text-emerald-400 border border-emerald-400/25 hover:bg-emerald-400 hover:text-[#07120e].

Gotchas — read before shipping

  • The grid-template-columns: repeat(3, minmax(0, 1fr)) uses minmax(0, ...) deliberately — the default 1fr resolves to minmax(auto, 1fr) and a long unbreakable string (like a coupon code or a URL in a feature name) forces the column wider than 1/3, breaking the three-tier design. Never drop the 0.
  • The .ps-01__sub has min-height: 38px so all three subheads align vertically even when the copy is one line vs two. If you translate this to a language where the subhead is longer (German averages ~30% more characters than English), bump to min-height: 56px and remove the mobile override to avoid a CLS pop.
  • The CTA rgba(52,211,153,0.12) fill against dark text at rest measures ~2.1:1 contrast for the border pattern — the emerald text against #0d1f18 is what carries the ~7:1 contrast for WCAG 1.4.3. Do not lower the text color's alpha thinking it's decorative; it's the primary readable state.
  • The check-mark icon uses -webkit-mask and mask with a data-URI SVG. Older Safari (< 15.4) requires the -webkit- prefix or the check disappears entirely; keep both lines. Do not switch to background-image unless you also recolor per-tier — the mask lets one hex value repaint every check via the background shorthand.
  • The :hover uses transform: translateY(-2px) + border-color — both compositor-only in modern engines. Never add box-shadow to the hover transition; box-shadow forces a paint on every frame and drops the interactive card off the compositor thread, spiking INP past 200ms on the 75th percentile mobile.
  • In React / Next.js, do not render this list from a tiers array without a stable key prop bound to tier slug (not index). If you A/B test tier order via GrowthBook or LaunchDarkly, an index key remounts the card on flip, firing a full paint mid-experiment and destroying the CLS reading for the exposure cohort.

Techniques used in this demo

Search CodeFronts

Loading…