21 CSS Pricing Sections13 / 21

Pure CSSMIT licensed

Editorial Two Column

A dense editorial pricing layout — left column carries the value-prop copy, right column stacks two compact tier rows like a printed price list. Neutral charcoal on cream, the Stripe / Basecamp documentation aesthetic.

Published

Live Demo
Try it

The code

<section class="ps-13" aria-label="Pricing">
  <div class="ps-13__grid">
    <div class="ps-13__copy">
      <span class="ps-13__eye">— Pricing</span>
      <h2>Two plans. <em>Pick one,</em> change later.</h2>
      <p>
        We don’t play games with feature gating, seat limits, or upsell pop-ups. Pick a plan, get
        the whole product, and move on with your work.
      </p>
      <p class="ps-13__fine">
        All plans include unlimited projects, every integration, and email support. Cancel any time,
        money back inside 30 days.
      </p>
      <a class="ps-13__link" href="#compare">See the full feature list →</a>
    </div>
    <div class="ps-13__tiers">
      <article class="ps-13__row">
        <header>
          <h3>Solo</h3>
          <span class="ps-13__pri">$15<em>/ month</em></span>
        </header>
        <p>For freelancers and indie builders shipping client work.</p>
        <ul>
          <li>Single workspace</li>
          <li>10 GB storage</li>
          <li>Email support</li>
        </ul>
        <a class="ps-13__cta" href="#solo">Choose Solo →</a>
      </article>
      <article class="ps-13__row ps-13__rec">
        <header>
          <h3>Studio <span class="ps-13__tag">Recommended</span></h3>
          <span class="ps-13__pri">$48<em>/ month</em></span>
        </header>
        <p>For small teams who run multiple client engagements.</p>
        <ul>
          <li>Unlimited workspaces</li>
          <li>250 GB storage</li>
          <li>Priority support &amp; onboarding</li>
          <li>Client billing &amp; white-label</li>
        </ul>
        <a class="ps-13__cta ps-13__cta-pri" href="#studio">Choose Studio →</a>
      </article>
    </div>
  </div>
</section>
.ps-13 {
  padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
  width: 100%;
  min-height: 100vh;
  background: #f5f1ea;
  color: #1c1c1e;
  font-family: 'Inter', system-ui, sans-serif;
}

.ps-13__grid {
  max-width: 1040px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 56px;
  align-items: start;
}

.ps-13__copy {
  padding-top: 6px;
}

.ps-13__eye {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.1em;
  color: #6b6b6e;
  margin-bottom: 14px;
}

.ps-13__copy h2 {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: clamp(28px, 4.4vw, 44px);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin: 0 0 18px;
}

.ps-13__copy h2 em {
  font-style: italic;
  color: #6b6b6e;
}

.ps-13__copy p {
  font-size: 15px;
  line-height: 1.65;
  color: #3d3d40;
  margin: 0 0 12px;
  max-width: 380px;
}

.ps-13__fine {
  font-size: 13px !important;
  color: #6b6b6e !important;
  padding-top: 12px;
  border-top: 1px solid #d8d2c5;
}

.ps-13__link {
  display: inline-block;
  margin-top: 12px;
  font-size: 13px;
  font-weight: 600;
  color: #1c1c1e;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
}

.ps-13__link:hover {
  color: #6b6b6e;
}

.ps-13__tiers {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ps-13__row {
  background: #fff;
  border: 1px solid #d8d2c5;
  border-radius: 6px;
  padding: 22px 22px 18px;
  transition: border-color 0.18s, box-shadow 0.18s;
}

.ps-13__row:hover {
  border-color: #1c1c1e;
  box-shadow: 4px 4px 0 0 #1c1c1e;
}

.ps-13__rec {
  border-color: #1c1c1e;
  box-shadow: 4px 4px 0 0 #1c1c1e;
}

.ps-13__row header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px dashed #d8d2c5;
}

.ps-13__row h3 {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 22px;
  font-weight: 700;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
}

.ps-13__tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: #1c1c1e;
  color: #f5f1ea;
  padding: 3px 8px;
  border-radius: 2px;
}

.ps-13__pri {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.ps-13__pri em {
  font-size: 11px;
  font-style: normal;
  color: #6b6b6e;
  font-weight: 500;
  margin-left: 4px;
  letter-spacing: 0;
}

.ps-13__row p {
  font-size: 13.5px;
  color: #3d3d40;
  margin: 0 0 10px;
  line-height: 1.5;
}

.ps-13__row ul {
  list-style: none;
  padding: 0;
  margin: 0 0 16px;
  font-size: 13px;
  line-height: 1.85;
  color: #3d3d40;
}

.ps-13__row ul li::before {
  content: '·';
  color: #1c1c1e;
  font-weight: 800;
  display: inline-block;
  width: 18px;
  font-size: 18px;
  line-height: 0.5;
  vertical-align: middle;
}

.ps-13__cta {
  display: inline-block;
  padding: 9px 16px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  border: 1.5px solid #1c1c1e;
  color: #1c1c1e;
  background: transparent;
  transition: background 0.18s, color 0.18s;
}

.ps-13__cta-pri {
  background: #1c1c1e;
  color: #f5f1ea;
}

.ps-13__cta:hover {
  background: #1c1c1e;
  color: #f5f1ea;
}

.ps-13__cta-pri:hover {
  background: #f5f1ea;
  color: #1c1c1e;
}

.ps-13__cta:focus-visible {
  outline: 2px solid #1c1c1e;
  outline-offset: 3px;
}

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

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

  .ps-13__row: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: Editorial Two Column
Source: https://codefronts.com/layouts/css-pricing-sections/editorial-two-column/

A dense editorial pricing layout — left column carries the value-prop copy, right column stacks two compact tier rows like a printed price list. Neutral charcoal on cream, the Stripe / Basecamp documentation aesthetic.
## HTML
```html
<section class="ps-13" aria-label="Pricing">
  <div class="ps-13__grid">
    <div class="ps-13__copy">
      <span class="ps-13__eye">— Pricing</span>
      <h2>Two plans. <em>Pick one,</em> change later.</h2>
      <p>
        We don’t play games with feature gating, seat limits, or upsell pop-ups. Pick a plan, get
        the whole product, and move on with your work.
      </p>
      <p class="ps-13__fine">
        All plans include unlimited projects, every integration, and email support. Cancel any time,
        money back inside 30 days.
      </p>
      <a class="ps-13__link" href="#compare">See the full feature list →</a>
    </div>
    <div class="ps-13__tiers">
      <article class="ps-13__row">
        <header>
          <h3>Solo</h3>
          <span class="ps-13__pri">$15<em>/ month</em></span>
        </header>
        <p>For freelancers and indie builders shipping client work.</p>
        <ul>
          <li>Single workspace</li>
          <li>10 GB storage</li>
          <li>Email support</li>
        </ul>
        <a class="ps-13__cta" href="#solo">Choose Solo →</a>
      </article>
      <article class="ps-13__row ps-13__rec">
        <header>
          <h3>Studio <span class="ps-13__tag">Recommended</span></h3>
          <span class="ps-13__pri">$48<em>/ month</em></span>
        </header>
        <p>For small teams who run multiple client engagements.</p>
        <ul>
          <li>Unlimited workspaces</li>
          <li>250 GB storage</li>
          <li>Priority support &amp; onboarding</li>
          <li>Client billing &amp; white-label</li>
        </ul>
        <a class="ps-13__cta ps-13__cta-pri" href="#studio">Choose Studio →</a>
      </article>
    </div>
  </div>
</section>
```
## CSS
```css
.ps-13 {
  padding: clamp(28px, 5vw, 56px) clamp(20px, 4vw, 40px);
  width: 100%;
  min-height: 100vh;
  background: #f5f1ea;
  color: #1c1c1e;
  font-family: 'Inter', system-ui, sans-serif;
}

.ps-13__grid {
  max-width: 1040px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 56px;
  align-items: start;
}

.ps-13__copy {
  padding-top: 6px;
}

.ps-13__eye {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.1em;
  color: #6b6b6e;
  margin-bottom: 14px;
}

.ps-13__copy h2 {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: clamp(28px, 4.4vw, 44px);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin: 0 0 18px;
}

.ps-13__copy h2 em {
  font-style: italic;
  color: #6b6b6e;
}

.ps-13__copy p {
  font-size: 15px;
  line-height: 1.65;
  color: #3d3d40;
  margin: 0 0 12px;
  max-width: 380px;
}

.ps-13__fine {
  font-size: 13px !important;
  color: #6b6b6e !important;
  padding-top: 12px;
  border-top: 1px solid #d8d2c5;
}

.ps-13__link {
  display: inline-block;
  margin-top: 12px;
  font-size: 13px;
  font-weight: 600;
  color: #1c1c1e;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
}

.ps-13__link:hover {
  color: #6b6b6e;
}

.ps-13__tiers {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ps-13__row {
  background: #fff;
  border: 1px solid #d8d2c5;
  border-radius: 6px;
  padding: 22px 22px 18px;
  transition: border-color 0.18s, box-shadow 0.18s;
}

.ps-13__row:hover {
  border-color: #1c1c1e;
  box-shadow: 4px 4px 0 0 #1c1c1e;
}

.ps-13__rec {
  border-color: #1c1c1e;
  box-shadow: 4px 4px 0 0 #1c1c1e;
}

.ps-13__row header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px dashed #d8d2c5;
}

.ps-13__row h3 {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 22px;
  font-weight: 700;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
}

.ps-13__tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: #1c1c1e;
  color: #f5f1ea;
  padding: 3px 8px;
  border-radius: 2px;
}

.ps-13__pri {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.ps-13__pri em {
  font-size: 11px;
  font-style: normal;
  color: #6b6b6e;
  font-weight: 500;
  margin-left: 4px;
  letter-spacing: 0;
}

.ps-13__row p {
  font-size: 13.5px;
  color: #3d3d40;
  margin: 0 0 10px;
  line-height: 1.5;
}

.ps-13__row ul {
  list-style: none;
  padding: 0;
  margin: 0 0 16px;
  font-size: 13px;
  line-height: 1.85;
  color: #3d3d40;
}

.ps-13__row ul li::before {
  content: '·';
  color: #1c1c1e;
  font-weight: 800;
  display: inline-block;
  width: 18px;
  font-size: 18px;
  line-height: 0.5;
  vertical-align: middle;
}

.ps-13__cta {
  display: inline-block;
  padding: 9px 16px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  border: 1.5px solid #1c1c1e;
  color: #1c1c1e;
  background: transparent;
  transition: background 0.18s, color 0.18s;
}

.ps-13__cta-pri {
  background: #1c1c1e;
  color: #f5f1ea;
}

.ps-13__cta:hover {
  background: #1c1c1e;
  color: #f5f1ea;
}

.ps-13__cta-pri:hover {
  background: #f5f1ea;
  color: #1c1c1e;
}

.ps-13__cta:focus-visible {
  outline: 2px solid #1c1c1e;
  outline-offset: 3px;
}

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

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

  .ps-13__row:hover {
    transform: none;
  }
}
```

How this works

The layout is a two-column CSS grid, grid-template-columns: 1.1fr 1fr with a 56px gutter — the left column is deliberately heavier so the value-prop copy anchors the visitor's first read, and the right column stacks two .ps-13__row tier cards as if they were entries in a printed price list. align-items: start pins both columns to the top so the copy does not vertically center against the tiers — that would break the magazine-page rhythm. The tier stack uses display: flex; flex-direction: column; gap: 14px, and each row is a solid #fff card with a 4px 4px 0 0 #1c1c1e flat-stamp shadow on the recommended Studio tier — the same shadow the hover state applies to Solo, which telegraphs "hover-to-preview" without a tooltip.

The palette is deliberately editorial: cream body (#f5f1ea), near-black ink (#1c1c1e), and warm-gray secondary text (#6b6b6e) — the three-value stack that Stripe's docs, 37signals blog, and Basecamp pricing all use. Typography carries the register: Playfair Display serif for h2 and tier names (font-size: 22px; font-weight: 700), Inter for body copy at 15px/1.65, and JetBrains Mono for the .ps-13__eye eyebrow and the small .ps-13__tag "Recommended" chip. Serif headline + monospace metadata is the editorial pricing signature.

Why this converts on editorial pricing and B2B SaaS: prose-heavy pricing framing borrows trust from print journalism — visitors read the left column as "considered offer," not "hard sell," which is exactly the reciprocity signal Cialdini identifies. The two-tier constraint is deliberate Iyengar-jam-shelf choice reduction (two options beat five for conversion on considered purchases), and the .ps-13__fine risk-reversal line ("Cancel any time, money back inside 30 days") sits directly under the value prop where hesitant readers look — Baymard's checkout research shows visible refund copy lifts trust-motivated conversions 30-45%.

Make it yours

  • Recolor to your brand by editing four values: cream background (#f5f1ea), ink black (#1c1c1e), warm gray (#6b6b6e), and hairline border (#d8d2c5). For newsletter/media SaaS swap cream to #fefaf3; for fintech-editorial swap ink to #0b1220 and cream to #f4f2ee.
  • Swap Playfair Display: 'Cormorant Garamond' for artisanal / handcrafted register, 'Source Serif Pro' for tech-editorial, 'GT Sectra' for luxury, 'IBM Plex Serif' for brutalist. Keep JetBrains Mono for the eyebrow and tag — the serif+mono pairing is the whole editorial signal.
  • Change the CTA shape: border-radius: 4px reads as "editorial stamp." Drop to 0 for brutalist ticket-stub CTAs. The 4px 4px 0 0 #1c1c1e flat shadow on .ps-13__rec pairs with sharp corners only — bumping radius above 6px makes the offset shadow look like a mistake.
  • For dark-mode: invert to #1a1815 background, #f5f1ea text, #a8a29e warm gray, keep white card bodies at #252220 and the flat-stamp shadow becomes 4px 4px 0 0 #f5f1ea. The Playfair italic emphasis stays untouched — cream-italic on ink is the strongest editorial pairing.
  • For Tailwind: bg-[#f5f1ea] font-sans on section, font-serif text-[clamp(28px,4.4vw,44px)] leading-[1.1] tracking-tight on h2, tier rows as bg-white border border-[#d8d2c5] rounded-[6px] hover:shadow-[4px_4px_0_0_#1c1c1e]. Use @font-face for Playfair — Google Fonts CDN blocks LCP by ~200ms.

Gotchas — read before shipping

  • The 4px 4px 0 0 #1c1c1e hover shadow is a paint operation, not a transform — hovering triggers a paint on a 22×22px card region which is cheap, but if you replicate this pattern on 6+ tiers per row you will see INP spike above 200ms on mid-tier mobile. Cap total simultaneous hover paints at 3.
  • Playfair Display's italic <em> inside the h2 works because Playfair ships true italics. If a browser fails to load Playfair and falls back to Georgia, Georgia's italics are acceptable but system-ui on Android renders synthetic obliques that look janky. Ship font-display: swap and preload the italic weight explicitly.
  • The .ps-13__fine uses !important on two properties because .ps-13__copy p has higher specificity than .ps-13__fine alone. This is a legit specificity-reset use of !important — do not remove it unless you also raise .ps-13__fine's selector (e.g. .ps-13__copy p.ps-13__fine).
  • The recommended-tier CTA uses color: #f5f1ea on background: #1c1c1e — contrast ratio ~14.8:1, comfortably clears WCAG 2.1 SC 1.4.3 AAA. The muted eyebrow at #6b6b6e on #f5f1ea however is only ~4.9:1, AA-only for the 12px size — do not drop it below 12px or you fail AA.
  • The dashed border-bottom: 1px dashed #d8d2c5 on the card header renders inconsistently across engines: Chrome draws 2px on/2px off, Safari draws 3px on/1px off, Firefox draws 2px on/3px off. If the dash pattern matters for brand consistency, replace with background-image: linear-gradient(90deg, #d8d2c5 50%, transparent 50%) at background-size: 6px 1px.
  • In Next.js App Router, 'Playfair Display' loaded via next/font/google deduplicates automatically, but Vue 3 + Vite with @fontsource ships one file per weight — importing italic + bold + regular triples the LCP font payload. Use @fontsource-variable/playfair-display for a single 40KB file instead.

Techniques used in this demo

Search CodeFronts

Loading…