Navigation

v0.0.4
Data display

Price

What something costs, set the way a price is read.

On this page

A price is what something costs, set the way a price is read: the figures large, the currency mark small and hung from their top, the period quiet on their baseline. It has no surface of its own. Put it in a plan's card, beside a product, or at the foot of an invoice.

Price

<div class="tray flex flex-wrap gap(4) max-w(480) mx-auto">  <div class="card card-flat grow(1) basis(200)">    <div class="card-header">      <h3 class="card-title">Starter</h3>      <p class="card-description">For one person and a few projects.</p>    </div>    <p class="price">      <span class="price-currency">$</span>      <span class="price-amount">9</span>      <span class="price-period">per month</span>    </p>    <div class="card-footer">      <button class="btn" type="button">Choose Starter</button>    </div>  </div>  <div class="card card-flat grow(1) basis(200)">    <div class="card-header">      <h3 class="card-title">Team</h3>      <p class="card-description">For a team that ships every day.</p>    </div>    <p class="price">      <s class="price-was">$39</s>      <span class="price-currency">$</span>      <span class="price-amount">29</span>      <span class="price-period">per month</span>    </p>    <div class="card-footer">      <button class="btn btn-primary" type="button">Choose Team</button>    </div>  </div></div>

#Parts

  • price-amount is the figures, in tabular numerals with a tight fit. It may be a word: Free, Custom.
  • price-currency is the currency mark. It is under half the size of the figures and its top is level with theirs, so it reads as part of the number without competing with it.
  • price-period says per what: a month, a seat, a thousand requests. It is small and muted on the baseline. Write it in words; "/mo" is read aloud as "slash mo".
  • price-was is a price that no longer holds. It stands before the amount, quiet and struck through. Use an <s> for it, which says the text is no longer accurate.

Write the parts in reading order: was, currency, amount, period. For a currency that follows its figures, put price-currency after price-amount.

#Sizes

The figures are 36px. price-sm is 24px, for a row or a small card, and price-lg is 56px, for the one price a page is about. Every part is sized from the figures, so --price-size scales the whole price to any size between.

Sizes

<p class="price price-sm">  <span class="price-currency">$</span>  <span class="price-amount">9</span>  <span class="price-period">per month</span></p><p class="price">  <span class="price-currency">$</span>  <span class="price-amount">29</span>  <span class="price-period">per month</span></p><p class="price price-lg">  <span class="price-currency">€</span>  <span class="price-amount">1,240</span>  <span class="price-period">per seat</span></p>

#Price or stat

A price is a cost to weigh. A measurement with a label and a change, such as revenue this month, is a stat. An amount that is one cell among many belongs in a table with table-numeric.

#Accessibility

  • The parts are read in the order they are written: "dollar 29 per month". Keep the currency mark as text, never as a background image.
  • A struck price is not announced as struck by every screen reader. Add a few words a reader does not see, such as "was" before it and "now" before the amount, when the difference matters.
  • Do not rely on the size of the figures to say which plan is recommended: say it in the card.

#Classes

ClassDescription
priceThe price on one line, 36px figures in tabular numerals with a tight fit
price-sm24px figures; the default is 36px. With price
price-lg56px figures, for the one price a page is about; the default is 36px. With price
price-amountThe figures, or a word such as Free
price-currencyThe currency mark, under half the size of the figures and level with their top
price-periodPer what, small and muted on the baseline: a month, a seat
price-wasThe price that no longer holds, quiet and struck through, before the amount

#Custom properties

PropertyDefaultDescription
--price-size2.25remSize of the figures; the other parts follow it

#Source

@master/ui/components/price.css
/* * Price: what something costs, set the way a price is read. * The amount is large, in tabular figures with a tight fit. The currency mark is small and hangs from the * top of the figures, level with their cap height; the period is small and quiet on their baseline. A price * that no longer holds stands before the amount, struck through, on a <s>. * Everything is sized from the amount, so one size class or one font-size scales the whole price. */@layer components {  .price {    --price-size: 2.25rem;    display: inline-flex;    align-items: baseline;    min-width: 0;    margin: 0;    color: var(--color-text-strong);    font: var(--font-weight-control) var(--price-size)/1 var(--font-family-sans);    font-feature-settings: inherit;    font-variant-numeric: tabular-nums;    letter-spacing: -.03em;    white-space: nowrap;    &.price-sm {      --price-size: 1.5rem;    }    &.price-lg {      --price-size: 3.5rem;      letter-spacing: -.04em;    }  }  /* The figures. */  .price-amount {    font: inherit;  }  /* The currency mark: under half the size of the figures, its top level with theirs. */  .price-currency {    align-self: flex-start;    margin-top: .16em;    margin-inline-end: .14em;    color: var(--color-text-body);    font-size: .46em;    letter-spacing: 0;    line-height: 1;  }  /* Per what: a month, a seat, a thousand requests. */  .price-period {    margin-inline-start: .3em;    color: var(--color-text-muted);    font-weight: 400;    font-size: max(.8125rem, .36em);    letter-spacing: 0;  }  /* The price that no longer holds: quiet, struck, before the one that does. */  .price-was {    margin-inline-end: .5em;    color: var(--color-text-muted);    font-weight: 400;    font-size: .5em;    letter-spacing: -.01em;    text-decoration-line: line-through;    /* The strike grows with the figures it crosses. */    text-decoration-thickness: max(1px, .07em);    text-decoration-color: var(--color-line-mark);  }}