PDFPipe

Events, hospitality and membership / ID-1 card

Membership card PDF template

An ID-1 wallet card with the organisation, the member, a membership number and a tier, on a dark ground that has to survive print.

When this document is the right one

A membership needs a physical token: a card shown at a door, kept in a wallet, and looked at occasionally by its owner. It is one of the few generated documents whose job is to be carried.

Why each part is there

The fields are visible in the markup. What is not visible is why they are present, which is the part that gets removed first when someone adapts a template for their own use.

  • The ID-1 rectangle, 85.6 by 53.98 millimetres, so the card fits every wallet slot designed for a bank card.
  • The member's name as the largest element, because that is what is checked at a door.
  • A membership number in a spaced monospace run, since it will be read aloud over a telephone.
  • A tier marker, if there is one, kept small: it matters to the organisation more than to the member.
  • A contact line, because a found card should be returnable.

The template

A complete file. Doctype, stylesheet, body: paste it into a renderer unchanged and it produces a finished ID-1 card page. Replace the sample data and the styling holds.

html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Membership card, M-4471</title>
<style>
  /* ID-1, the bank card rectangle, so it fits a wallet slot. 5mm of clear
     space on every side because commercial trimming wanders by about a
     millimetre and edge-aligned content shows it. */
  @page { size: 85.6mm 53.98mm; margin: 0; }
  * { box-sizing: border-box; }
  body { margin: 0; height: 53.98mm; padding: 5mm;
         font: 7.5pt/1.3 "Helvetica Neue", Arial, sans-serif;
         color: #f4f1ea; background: #1f2b25;
         print-color-adjust: exact; -webkit-print-color-adjust: exact;
         display: flex; flex-direction: column; }

  header { display: flex; justify-content: space-between; align-items: flex-start; }
  .org { font-size: 8.5pt; font-weight: 700; letter-spacing: 0.12em;
         text-transform: uppercase; }
  .tier { border: 1px solid #7f9b8d; border-radius: 1mm; padding: 0.6mm 2mm;
          font-size: 6.5pt; letter-spacing: 0.1em; text-transform: uppercase; color: #a8c3b6; }

  .name { margin-top: auto; font-size: 12pt; font-weight: 700; letter-spacing: 0.01em; }
  /* Nothing on a card should be below about 7pt. Under that it stops being
     readable and becomes texture. */
  .number { font-size: 9pt; letter-spacing: 0.18em; font-variant-numeric: tabular-nums;
            margin-top: 1mm; color: #a8c3b6; }

  footer { display: flex; justify-content: space-between; align-items: flex-end;
           margin-top: 3mm; font-size: 6.5pt; color: #8ba99b; letter-spacing: 0.06em; }
  footer .valid { text-transform: uppercase; }
  footer .valid strong { display: block; font-size: 8pt; color: #f4f1ea;
                         letter-spacing: 0.04em; }
</style>
</head>
<body>
  <header>
    <div class="org">Rivermouth Wetland Trust</div>
    <div class="tier">Life</div>
  </header>

  <div class="name">Helen Ashworth</div>
  <div class="number">M 4471 0882 19</div>

  <footer>
    <div class="valid">Member since<strong>2019</strong></div>
    <div>rivermouth.example &middot; 01392 440 118</div>
  </footer>
</body>
</html>

The layout decision worth understanding

The dark ground uses print-color-adjust: exact, without which the card prints as black text on white and stops looking like a card at all. Nothing on it is set below 6.5pt, because under about 7pt type at this size stops being readable and becomes texture.

The mistake people make adapting it

Designing to the ID-1 rectangle and printing on US 3.5 by 2 inch stock, or the reverse. The two differ by more than 3mm in each direction, which is enough that centred content is visibly off and edge-aligned content is cut.

Rendering it

The page box is declared in the template's own CSS as Business card, so the size travels with the markup rather than living in the code that calls the renderer. Business card is not one of the six named formats the API accepts, so set prefer_css_page_size on the request and the renderer will use the page box the document declares.

bash
curl -X POST https://api.pdfpipe.xyz/v1/pdf \
  -H "Authorization: Bearer $PDFPIPE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<!doctype html>...",
    "options": { "prefer_css_page_size": true }
  }' \
  --output membership-card.pdf

Frequently asked

Can I use this template commercially?

Yes. Copy it, change it, ship it. It is sample markup written to be taken, and the sample data in it is invented, so replace the names and the numbers before anyone sees it.

Why is the page size in the CSS rather than in the API call?

Because a membership card is a ID-1 card document, and that is a property of the document rather than of the code that renders it. Declaring it in the page box means the size cannot be lost between the template and the call, which is the usual way a document ends up on the wrong paper.

Will it look the same in every renderer?

The layout will, because it uses ordinary CSS. The page break behaviour will not: break-inside and break-after are implemented differently by browser engines and by dedicated print engines, and some of the paged media specification is not implemented in browser renders at all. That difference is documented per property in the paged CSS reference.

Other templates

Documents from the same part of a business, and one from each of the other groups.

Paste the template into the playground and get the PDF back. No signup, no key.