Navigation

v0.0.4
Marketing blocks

Pricing

Plans side by side, with one recommended.

A pricing block sets the plans side by side: a name, a price, who it is for, one button, and what is included. One plan is recommended, and it is the only one that stands out.

Pricing

<section class="container-inline px-lg py-4xl" aria-labelledby="pricing-title">  <div class="flex flex-col gap-2xl max-w(1040) mx-auto">    <header class="flex flex-col items-center gap-sm text-center">      <p class="eyebrow">Pricing</p>      <h2 class="heading heading-2xl" id="pricing-title">Free to start. Fair when you grow.</h2>      <p class="lead max-w(480)">Every plan deploys the same way. You pay for the team, not for the traffic.</p>    </header>    <div class="grid gap-md items-start grid-cols(3)@container(--4xl)">      <article class="sheet sheet-raised flex flex-col gap-lg p-lg">        <header class="flex flex-col gap-xs">          <div class="flex items-center justify-between gap-sm">            <h3 class="heading heading-sm">Hobby</h3>          </div>          <p class="price">            <span class="price-currency">$</span>            <span class="price-amount">0</span>            <span class="price-period">forever</span>          </p>          <p class="m(0) leading-md">For side projects and trying things out.</p>        </header>        <a class="btn" href="#">Start for free</a>        <ul class="bullets bullets-check">          <li class="bullets-item">One project</li>          <li class="bullets-item">Previews for every branch</li>          <li class="bullets-item">Community support</li>        </ul>      </article>      <article class="sheet flex flex-col gap-lg p-lg">        <header class="flex flex-col gap-xs">          <div class="flex items-center justify-between gap-sm">            <h3 class="heading heading-sm">Pro</h3>            <span class="badge badge-ink badge-pill">Most popular</span>          </div>          <p class="price">            <span class="price-currency">$</span>            <span class="price-amount">20</span>            <span class="price-period">per member, monthly</span>          </p>          <p class="m(0) leading-md">For teams that ship to real visitors.</p>        </header>        <a class="btn btn-brand" href="#">Start a trial</a>        <ul class="bullets bullets-check">          <li class="bullets-item">Unlimited projects</li>          <li class="bullets-item">Fourteen regions</li>          <li class="bullets-item">Analytics and firewall</li>          <li class="bullets-item">Email support, next day</li>        </ul>      </article>      <article class="sheet sheet-raised flex flex-col gap-lg p-lg">        <header class="flex flex-col gap-xs">          <div class="flex items-center justify-between gap-sm">            <h3 class="heading heading-sm">Enterprise</h3>          </div>          <p class="price">            <span class="price-amount">Custom</span>          </p>          <p class="m(0) leading-md">For organizations with their own rules.</p>        </header>        <a class="btn" href="#">Talk to sales</a>        <ul class="bullets bullets-check">          <li class="bullets-item">Single sign-on and audit log</li>          <li class="bullets-item">A 99.99% uptime agreement</li>          <li class="bullets-item">A named engineer</li>          <li class="bullets-item">Invoices and purchase orders</li>        </ul>      </article>    </div>    <p class="m(0) text-center text-xs fg-text-muted">Prices are in US dollars and exclude tax. Cancel any time.</p>  </div></section>

Blocks are markup to copy. They take the page's own text color and size; the previews set fg-text-body text-sm on the body. Each block is a size container, so it reflows by its own width.

#What is in it

  • Three sheets in a grid. One column until 56rem of block, then grid-cols(3)@container(--4xl). items-start lets each plan be as tall as its own list.
  • The recommended plan is lifted, not colored. It is a sheet at the default elevation among sheet-raised neighbors, with a badge-ink and the page's one btn-brand. Depth, a word and the one hued button: three quiet signals, no colored border.
  • The price is a price: large figures, the currency mark hung small from their top, and the period beside them in muted ink on the same baseline.
  • The button comes before the list. A visitor who has decided should not have to pass the features to act.
  • What is included is bullets with bullets-check: a check in ink hangs before each line, as decoration. The line reads without it.

Order the plans cheapest first. If one plan fits nearly everyone, say so in its description instead of adding a fourth.

#A comparison

Under the plans, a table answers the questions the cards cannot: a row per feature, a column per plan. On a narrow screen it scrolls sideways in a scroll area inside its sheet, which fades the edge where columns continue.

A comparison

<section class="container-inline px-lg py-4xl" aria-labelledby="compare-title">  <div class="flex flex-col gap-xl max-w(880) mx-auto">    <h2 class="heading heading-xl" id="compare-title">Compare the plans</h2>    <div class="sheet overflow-hidden">      <div class="scroll-area scroll-area-inline" tabindex="0" role="region" aria-labelledby="compare-title">        <table class="table">          <thead>            <tr class="table-row">              <th class="table-heading" scope="col">                <span class="sr-only">Feature</span>              </th>              <th class="table-heading" scope="col">Hobby</th>              <th class="table-heading" scope="col">Pro</th>              <th class="table-heading" scope="col">Enterprise</th>            </tr>          </thead>          <tbody>            <tr class="table-row">              <th class="table-cell table-primary text-left" scope="row">Projects</th>              <td class="table-cell">1</td>              <td class="table-cell">Unlimited</td>              <td class="table-cell">Unlimited</td>            </tr>            <tr class="table-row">              <th class="table-cell table-primary text-left" scope="row">Regions</th>              <td class="table-cell">1</td>              <td class="table-cell">14</td>              <td class="table-cell">14</td>            </tr>            <tr class="table-row">              <th class="table-cell table-primary text-left" scope="row">Build minutes</th>              <td class="table-cell">100 a month</td>              <td class="table-cell">400 per member</td>              <td class="table-cell">Custom</td>            </tr>            <tr class="table-row">              <th class="table-cell table-primary text-left" scope="row">Analytics</th>              <td class="table-cell fg-text-muted">                <span aria-hidden="true">–</span>                <span class="sr-only">Not included</span>              </td>              <td class="table-cell">                <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">                  <path d="m5 12 5 5L20 7" />                </svg>                <span class="sr-only">Included</span>              </td>              <td class="table-cell">                <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">                  <path d="m5 12 5 5L20 7" />                </svg>                <span class="sr-only">Included</span>              </td>            </tr>            <tr class="table-row">              <th class="table-cell table-primary text-left" scope="row">Firewall rules</th>              <td class="table-cell fg-text-muted">                <span aria-hidden="true">–</span>                <span class="sr-only">Not included</span>              </td>              <td class="table-cell">                <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">                  <path d="m5 12 5 5L20 7" />                </svg>                <span class="sr-only">Included</span>              </td>              <td class="table-cell">                <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">                  <path d="m5 12 5 5L20 7" />                </svg>                <span class="sr-only">Included</span>              </td>            </tr>            <tr class="table-row">              <th class="table-cell table-primary text-left" scope="row">Single sign-on</th>              <td class="table-cell fg-text-muted">                <span aria-hidden="true">–</span>                <span class="sr-only">Not included</span>              </td>              <td class="table-cell fg-text-muted">                <span aria-hidden="true">–</span>                <span class="sr-only">Not included</span>              </td>              <td class="table-cell">                <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">                  <path d="m5 12 5 5L20 7" />                </svg>                <span class="sr-only">Included</span>              </td>            </tr>            <tr class="table-row">              <th class="table-cell table-primary text-left" scope="row">Uptime agreement</th>              <td class="table-cell fg-text-muted">                <span aria-hidden="true">–</span>                <span class="sr-only">Not included</span>              </td>              <td class="table-cell fg-text-muted">                <span aria-hidden="true">–</span>                <span class="sr-only">Not included</span>              </td>              <td class="table-cell">99.99%</td>            </tr>          </tbody>        </table>      </div>    </div>  </div></section>

A check and a dash are not words: each is hidden from assistive technology and carries visually hidden text, "Included" or "Not included". The scroll area has tabindex="0" and takes the heading's name, so the keyboard can scroll it.

#Accessibility

  • Each plan is an <article> with its name as an <h3> under the block's <h2>.
  • The badge is text, "Most popular", so the recommendation is not carried by position or depth alone.
  • In the table, the first cell of each row is a <th scope="row">, so a cell is announced with its feature and its plan.
  • Write the period into the price. "$20" alone is not a price.