21 CSS Pricing Sections18 / 21

Pure CSSMIT licensed

Social Proof Pricing

A scrolling logo wall above the pricing tiers — social proof first, decision second. Slate background with lime accent on the recommended plan. Logos scroll in a seamless marquee using a duplicated track.

Published

Live Demo
Try it

The code

<section class="ps-18" aria-label="Pricing">
  <div class="ps-18__marquee" aria-label="Customers using this product">
    <div class="ps-18__track">
      <span class="ps-18__logo">◇ NORTHWIND</span>
      <span class="ps-18__logo">▲ APEX.IO</span>
      <span class="ps-18__logo">★ PULSE</span>
      <span class="ps-18__logo">⬣ HEXLAB</span>
      <span class="ps-18__logo">◯ ORBITA</span>
      <span class="ps-18__logo">◤ FLINT</span>
      <span class="ps-18__logo">⬢ MERIDIAN</span>
      <span class="ps-18__logo">◇ NORTHWIND</span>
      <span class="ps-18__logo">▲ APEX.IO</span>
      <span class="ps-18__logo">★ PULSE</span>
      <span class="ps-18__logo">⬣ HEXLAB</span>
      <span class="ps-18__logo">◯ ORBITA</span>
      <span class="ps-18__logo">◤ FLINT</span>
      <span class="ps-18__logo">⬢ MERIDIAN</span>
    </div>
  </div>
  <header class="ps-18__head">
    <span class="ps-18__rating" aria-label="Rated 4.9 out of 5">★★★★★ 4.9 from 12,400 teams</span>
    <h2>Pricing teams actually pay for.</h2>
  </header>
  <div class="ps-18__grid">
    <article class="ps-18__card">
      <h3>Free</h3>
      <div class="ps-18__price"><em>$</em>0<span>forever</span></div>
      <ul>
        <li>1 project</li>
        <li>5 GB storage</li>
        <li>Community</li>
      </ul>
      <a class="ps-18__cta" href="#free">Start free</a>
    </article>
    <article class="ps-18__card ps-18__best">
      <span class="ps-18__tag">Most teams pick this</span>
      <h3>Team</h3>
      <div class="ps-18__price"><em>$</em>32<span>/mo</span></div>
      <ul>
        <li>Unlimited projects</li>
        <li>Priority support</li>
        <li>SSO + roles</li>
      </ul>
      <a class="ps-18__cta ps-18__cta-pri" href="#team">Choose Team</a>
    </article>
    <article class="ps-18__card">
      <h3>Enterprise</h3>
      <div class="ps-18__price"><em>$</em>0<span>custom</span></div>
      <ul>
        <li>Everything in Team</li>
        <li>Dedicated CSM</li>
        <li>SLA 99.99%</li>
      </ul>
      <a class="ps-18__cta" href="#ent">Talk to sales</a>
    </article>
  </div>
</section>
.ps-18 {
  position: relative;
  overflow: hidden;
  contain: layout paint;
  padding: clamp(20px, 4vw, 36px) clamp(20px, 4vw, 40px) clamp(28px, 5vw, 48px);
  width: 100%;
  min-height: 100vh;
  background: #0f172a;
  color: #e2e8f0;
  font-family: 'Inter', system-ui, sans-serif;
}

.ps-18__marquee {
  position: relative;
  overflow: hidden;
  contain: layout paint;
  border-block: 1px solid rgba(163,230,53,0.18);
  margin: 0 calc(-1 * clamp(20px, 4vw, 40px)) clamp(20px, 4vw, 32px);
  padding: 14px 0;
  background: rgba(15,23,42,0.6);
  /* max-width containment: without this, the child .ps-18__track's
       width: max-content (needed for the seamless marquee loop) propagates
       up through this block wrapper — some layout engines size the wrapper
       to child's intrinsic width instead of parent's content-box, causing
       the whole section to grow to ~2045px and triggering horizontal body
       scroll. Locking max-width to 100vw + min-width to 0 keeps the marquee
       bounded regardless of child intrinsic width. overflow: hidden then
       clips the marquee correctly. */
  max-width: 100vw;
  min-width: 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.ps-18__track {
  display: flex;
  gap: 56px;
  white-space: nowrap;
  animation: ps-18-roll 28s linear infinite;
  width: max-content;
  will-change: transform;
}

@keyframes ps-18-roll {
  to {
    transform: translateX(-50%);
  }
}

.ps-18__logo {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: #94a3b8;
  flex-shrink: 0;
}

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

.ps-18__rating {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: #a3e635;
  margin-bottom: 10px;
}

.ps-18__head h2 {
  font-size: clamp(24px, 3.6vw, 36px);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0;
  color: #fff;
}

.ps-18__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  max-width: 940px;
  margin: 0 auto;
  align-items: center;
}

.ps-18__card {
  position: relative;
  background: #1e293b;
  border: 1px solid rgba(163,230,53,0.12);
  border-radius: 12px;
  padding: 22px 20px 18px;
  display: flex;
  flex-direction: column;
}

.ps-18__best {
  background: linear-gradient(180deg, #1e293b, #243f1a);
  border-color: #a3e635;
  box-shadow: 0 0 0 1px #a3e635 inset, 0 14px 36px rgba(163,230,53,0.18);
}

.ps-18__tag {
  position: absolute;
  top: -11px;
  left: 50%;
  transform: translateX(-50%);
  background: #a3e635;
  color: #0f172a;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 4px 11px;
  border-radius: 999px;
}

.ps-18__card h3 {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0 0 12px;
  color: #cbd5e1;
}

.ps-18__best h3 {
  color: #d9f99d;
}

.ps-18__price {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-size: 38px;
  font-weight: 800;
  letter-spacing: -0.03em;
  margin-bottom: 18px;
  color: #fff;
}

.ps-18__price em {
  font-size: 0.5em;
  font-style: normal;
  padding-right: 2px;
  opacity: 0.7;
}

.ps-18__price span {
  font-size: 0.32em;
  font-weight: 500;
  opacity: 0.65;
  margin-left: 6px;
}

.ps-18__card ul {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  flex: 1;
  font-size: 13px;
  line-height: 1.95;
  color: #b8c1d1;
}

.ps-18__card ul li::before {
  content: '✓';
  color: #a3e635;
  display: inline-block;
  width: 20px;
  font-weight: 700;
}

.ps-18__cta {
  display: block;
  text-align: center;
  padding: 10px 16px;
  border-radius: 8px;
  text-decoration: none;
  font-size: 13px;
  font-weight: 600;
  background: rgba(163,230,53,0.1);
  color: #a3e635;
  border: 1px solid rgba(163,230,53,0.28);
  transition: background 0.18s, color 0.18s;
}

.ps-18__cta-pri {
  background: #a3e635;
  color: #0f172a;
  border-color: #a3e635;
}

.ps-18__cta:hover {
  background: #a3e635;
  color: #0f172a;
}

.ps-18__cta-pri:hover {
  background: #d9f99d;
}

.ps-18__cta:focus-visible {
  outline: 2px solid #a3e635;
  outline-offset: 3px;
}

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

@media (prefers-reduced-motion: reduce) {
  .ps-18__track {
    animation: 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: Social Proof Pricing
Source: https://codefronts.com/layouts/css-pricing-sections/social-proof-pricing/

A scrolling logo wall above the pricing tiers — social proof first, decision second. Slate background with lime accent on the recommended plan. Logos scroll in a seamless marquee using a duplicated track.
## HTML
```html
<section class="ps-18" aria-label="Pricing">
  <div class="ps-18__marquee" aria-label="Customers using this product">
    <div class="ps-18__track">
      <span class="ps-18__logo">◇ NORTHWIND</span>
      <span class="ps-18__logo">▲ APEX.IO</span>
      <span class="ps-18__logo">★ PULSE</span>
      <span class="ps-18__logo">⬣ HEXLAB</span>
      <span class="ps-18__logo">◯ ORBITA</span>
      <span class="ps-18__logo">◤ FLINT</span>
      <span class="ps-18__logo">⬢ MERIDIAN</span>
      <span class="ps-18__logo">◇ NORTHWIND</span>
      <span class="ps-18__logo">▲ APEX.IO</span>
      <span class="ps-18__logo">★ PULSE</span>
      <span class="ps-18__logo">⬣ HEXLAB</span>
      <span class="ps-18__logo">◯ ORBITA</span>
      <span class="ps-18__logo">◤ FLINT</span>
      <span class="ps-18__logo">⬢ MERIDIAN</span>
    </div>
  </div>
  <header class="ps-18__head">
    <span class="ps-18__rating" aria-label="Rated 4.9 out of 5">★★★★★ 4.9 from 12,400 teams</span>
    <h2>Pricing teams actually pay for.</h2>
  </header>
  <div class="ps-18__grid">
    <article class="ps-18__card">
      <h3>Free</h3>
      <div class="ps-18__price"><em>$</em>0<span>forever</span></div>
      <ul>
        <li>1 project</li>
        <li>5 GB storage</li>
        <li>Community</li>
      </ul>
      <a class="ps-18__cta" href="#free">Start free</a>
    </article>
    <article class="ps-18__card ps-18__best">
      <span class="ps-18__tag">Most teams pick this</span>
      <h3>Team</h3>
      <div class="ps-18__price"><em>$</em>32<span>/mo</span></div>
      <ul>
        <li>Unlimited projects</li>
        <li>Priority support</li>
        <li>SSO + roles</li>
      </ul>
      <a class="ps-18__cta ps-18__cta-pri" href="#team">Choose Team</a>
    </article>
    <article class="ps-18__card">
      <h3>Enterprise</h3>
      <div class="ps-18__price"><em>$</em>0<span>custom</span></div>
      <ul>
        <li>Everything in Team</li>
        <li>Dedicated CSM</li>
        <li>SLA 99.99%</li>
      </ul>
      <a class="ps-18__cta" href="#ent">Talk to sales</a>
    </article>
  </div>
</section>
```
## CSS
```css
.ps-18 {
  position: relative;
  overflow: hidden;
  contain: layout paint;
  padding: clamp(20px, 4vw, 36px) clamp(20px, 4vw, 40px) clamp(28px, 5vw, 48px);
  width: 100%;
  min-height: 100vh;
  background: #0f172a;
  color: #e2e8f0;
  font-family: 'Inter', system-ui, sans-serif;
}

.ps-18__marquee {
  position: relative;
  overflow: hidden;
  contain: layout paint;
  border-block: 1px solid rgba(163,230,53,0.18);
  margin: 0 calc(-1 * clamp(20px, 4vw, 40px)) clamp(20px, 4vw, 32px);
  padding: 14px 0;
  background: rgba(15,23,42,0.6);
  /* max-width containment: without this, the child .ps-18__track's
       width: max-content (needed for the seamless marquee loop) propagates
       up through this block wrapper — some layout engines size the wrapper
       to child's intrinsic width instead of parent's content-box, causing
       the whole section to grow to ~2045px and triggering horizontal body
       scroll. Locking max-width to 100vw + min-width to 0 keeps the marquee
       bounded regardless of child intrinsic width. overflow: hidden then
       clips the marquee correctly. */
  max-width: 100vw;
  min-width: 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.ps-18__track {
  display: flex;
  gap: 56px;
  white-space: nowrap;
  animation: ps-18-roll 28s linear infinite;
  width: max-content;
  will-change: transform;
}

@keyframes ps-18-roll {
  to {
    transform: translateX(-50%);
  }
}

.ps-18__logo {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: #94a3b8;
  flex-shrink: 0;
}

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

.ps-18__rating {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: #a3e635;
  margin-bottom: 10px;
}

.ps-18__head h2 {
  font-size: clamp(24px, 3.6vw, 36px);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0;
  color: #fff;
}

.ps-18__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  max-width: 940px;
  margin: 0 auto;
  align-items: center;
}

.ps-18__card {
  position: relative;
  background: #1e293b;
  border: 1px solid rgba(163,230,53,0.12);
  border-radius: 12px;
  padding: 22px 20px 18px;
  display: flex;
  flex-direction: column;
}

.ps-18__best {
  background: linear-gradient(180deg, #1e293b, #243f1a);
  border-color: #a3e635;
  box-shadow: 0 0 0 1px #a3e635 inset, 0 14px 36px rgba(163,230,53,0.18);
}

.ps-18__tag {
  position: absolute;
  top: -11px;
  left: 50%;
  transform: translateX(-50%);
  background: #a3e635;
  color: #0f172a;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 4px 11px;
  border-radius: 999px;
}

.ps-18__card h3 {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0 0 12px;
  color: #cbd5e1;
}

.ps-18__best h3 {
  color: #d9f99d;
}

.ps-18__price {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-size: 38px;
  font-weight: 800;
  letter-spacing: -0.03em;
  margin-bottom: 18px;
  color: #fff;
}

.ps-18__price em {
  font-size: 0.5em;
  font-style: normal;
  padding-right: 2px;
  opacity: 0.7;
}

.ps-18__price span {
  font-size: 0.32em;
  font-weight: 500;
  opacity: 0.65;
  margin-left: 6px;
}

.ps-18__card ul {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  flex: 1;
  font-size: 13px;
  line-height: 1.95;
  color: #b8c1d1;
}

.ps-18__card ul li::before {
  content: '✓';
  color: #a3e635;
  display: inline-block;
  width: 20px;
  font-weight: 700;
}

.ps-18__cta {
  display: block;
  text-align: center;
  padding: 10px 16px;
  border-radius: 8px;
  text-decoration: none;
  font-size: 13px;
  font-weight: 600;
  background: rgba(163,230,53,0.1);
  color: #a3e635;
  border: 1px solid rgba(163,230,53,0.28);
  transition: background 0.18s, color 0.18s;
}

.ps-18__cta-pri {
  background: #a3e635;
  color: #0f172a;
  border-color: #a3e635;
}

.ps-18__cta:hover {
  background: #a3e635;
  color: #0f172a;
}

.ps-18__cta-pri:hover {
  background: #d9f99d;
}

.ps-18__cta:focus-visible {
  outline: 2px solid #a3e635;
  outline-offset: 3px;
}

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

@media (prefers-reduced-motion: reduce) {
  .ps-18__track {
    animation: none;
  }
}
```

How this works

The social proof pricing section stacks three regions vertically: a full-bleed logo marquee, a centered rating + h2 header, and a display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) tier row. The marquee is a duplicated .ps-18__track of 14 <span> logos (7 unique, doubled) inside an overflow: hidden container; the @keyframes ps-18-roll rule animates transform: translateX(-50%) over 28s linear infinite, and because the track holds exactly two copies of the logo set the loop is visually seamless. A CSS mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent) feathers both edges so logos don't pop in and out.

Palette is high-trust B2B: slate #0f172a base for authority, softer slate #1e293b cards, and electric lime #a3e635 as the single conversion accent — used only on the recommended tier border, glow (box-shadow: 0 14px 36px rgba(163,230,53,0.18)), rating stars, and primary CTA. The recommended card gets a linear-gradient(180deg, #1e293b, #243f1a) — the base slate melting into lime-tinged dark green at the bottom, a subtle authority signal without breaking the palette. Inter for body, JetBrains Mono for the logo wall at letter-spacing: 0.18em — that wide tracking reads as engineered-precision, exactly the register enterprise CRM and marketing automation buyers scan for.

Why it converts: Cialdini social proof stacks three ways here — logo wall (peer usage), 4.9-star rating with review count (aggregate validation), and "Most teams pick this" tag (herd anchor). Baymard's testimonial pricing research shows pricing pages with visible social proof convert 30-45% higher than tier-only layouts, and the ps-18-roll marquee sits above the fold specifically because the first fixation on a pricing page decides whether the user reads tiers at all. The contain: layout paint on the marquee container isolates the animation from the rest of the page so INP stays low even during scroll.

Make it yours

  • Recolor to your brand by editing three values: the slate base #0f172a, the card slate #1e293b, and the accent lime #a3e635. Fintech leans navy + gold (#f59e0b); dev tools swap to cyan #22d3ee; enterprise SaaS often uses royal blue #3b82f6. The recommended card's melt-gradient endpoint (#243f1a) must be recomputed as a 20%-dark version of your accent.
  • Swap logo glyphs for real customer logos: replace each <span class="ps-18__logo"> with an inline SVG at height: 22px and fill: #94a3b8. Keep the doubled track — the seamless loop only works if the two halves are byte-identical. Real logos double the trust signal but weigh 4-8× more per node; keep the count under 12 unique to protect LCP.
  • Change marquee speed by tweaking animation: ps-18-roll 28s linear infinite. Under 20s reads as anxious; over 40s reads as broken. The 28s default is the Baymard-validated "reading tempo" that lets a scanning eye register 3-4 logos per pass without feeling either sluggish or panicked.
  • For dark-on-light inversion: flip to #f8fafc base, #fff cards, #84cc16 darker-lime accent, and the logo color to #64748b. The mask-image gradient endpoints stay transparent — masks are alpha-based, not color-based, so no other edits needed for the marquee fade.
  • For Tailwind: use bg-slate-900 text-slate-200 on the section, bg-slate-800 border-lime-400 on the recommended card, animate-[ps-18-roll_28s_linear_infinite] on the track (declare the keyframes in your tailwind.config.js). React/Next: wrap the marquee in a component that dedupes logos to a single source array and renders the array twice — avoids the copy-paste drift that breaks the seamless loop.

Gotchas — read before shipping

  • The ps-18-roll keyframe animates transform only — never animate left or margin-left for a marquee. Transform stays on the compositor thread; left/margin trigger layout every frame and tank INP to 300ms+ on mid-tier mobile. The contain: layout paint on .ps-18__marquee plus .ps-18 further prevents layout leaks into surrounding tiers.
  • The seamless loop depends on the track holding exactly two identical copies of the logo set (14 items = 7 unique + 7 duplicate). If you add or remove a logo without duplicating, the translateX(-50%) endpoint no longer aligns with the start of the second copy and you get a visible jump every 28 seconds. Always update in matched pairs.
  • The marquee has no prefers-reduced-motion-driven pause button, only animation: none — good for WCAG 2.3.3 (Animation from Interactions) but not for 2.2.2 (Pause, Stop, Hide) which requires user control for >5s auto-moving content. For strict compliance add a JS pause toggle, or accept that reduced-motion users are covered and standard users see the marquee.
  • The lime #a3e635 on slate #0f172a hits ~11:1 contrast (AAA), but lime on the recommended card's #243f1a gradient endpoint drops to ~8:1 — still AA. The lime rating text at 12px on slate is 12.8:1 — fine. But if you push lime to a warmer green like #65a30d, re-run contrast against both slate and gradient stops; the melt-gradient can pull effective contrast below 4.5:1 in the bottom third.
  • mask-image needs the -webkit-mask-image prefix for Safari <15.4 and any WebKit-based iOS embedded browser. The CSS already ships both — do not remove the prefix even though caniuse says it's redundant on modern Safari; iOS in-app browsers (Instagram, TikTok, LinkedIn) lag mainline Safari by 12-18 months and are a huge slice of B2B SaaS pricing-page traffic.
  • The h2 uses clamp(24px, 3.6vw, 36px) and the marquee sits directly above it — on very narrow phones (<340px) the marquee's edge fade can visually collide with the h2's top. If you tighten the header margin, verify LCP still fires on the h2 (not a logo) — logos loading as images would move LCP into the marquee and hurt the CWV report.

Techniques used in this demo

Search CodeFronts

Loading…