Formatting and locale / Names, addresses and identifiers
Phone numbers on a document somebody has to dial from abroad
A number printed in a national format, which cannot be dialled from outside the country it belongs to and gives the reader no way to work out what is missing.
The defect
National formats drop the country code and often add a trunk digit that has to be removed when dialling internationally. Printed on a document that leaves the country, such a number is not dialable and, worse, is not obviously undialable: the reader tries it, it fails, and there is nothing on the page that tells them what to prepend or which digit to drop. Grouping is the second half of the problem. A number printed as an unbroken run of eleven or twelve digits is hard to read and hard to transcribe, and the grouping conventions that make it readable differ by country.
What it does to the document
The international form is longer than the national one, so a contact block laid out for the short form wraps once the country code goes in. It belongs in the contact block alongside the email address, where the same nowrap and overflow rules apply for the same reason.
The decisions
Reasons rather than a description of the code. Formatting rules are data that changes, so most of these are about taking the rule from a maintained source rather than encoding today's answer.
- Print in the international form with the country code, for any document that might be read outside the country. It is dialable everywhere and unambiguous.
- Store in a canonical international form and format for display, rather than storing whatever was typed.
- Group the digits for readability using a library that knows the destination's convention, rather than inserting spaces at a fixed interval.
- Keep the whole number unbreakable. A phone number split across a line is routinely dialled wrong.
- Where an extension exists, separate it clearly and label it, because an extension run onto the end of the number is dialled as part of it.
- Do not print a national and an international form of the same number side by side. Two numbers that look different are two numbers to a reader in a hurry.
In code
The formatting happens before the markup exists, so this is mostly code rather than CSS. The wrong version is kept in a comment where the wrong version is the thing people write.
// Store canonical, format for display.
const stored = "+441144960022"; // canonical, international
// International form, grouped for the destination's convention.
// Use a phone-number library rather than inserting spaces at a fixed
// interval, because grouping conventions differ by country.
const display = formatInternational(stored); // e.g. "+44 114 496 0022"
/* Keep it unbreakable and set it in a face where the digits are
unambiguous, because this is a transcribed field:
.tel {
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
Extension separated and labelled, never run onto the end:
<span class="tel">+44 114 496 0022</span> ext. 214 */What people do instead
Printing the number exactly as it was typed into the system. Different records then carry different formats, some with country codes and some without, and the document ends up with two contact numbers in visibly different shapes on the same page.
How to find out rather than assume
Take the number off a printed copy and dial it from another country. If it does not connect, or if you had to work out what to add, the format is wrong. Then confirm it did not wrap at the narrowest column it appears in.
Where the API sits in this
Nowhere, and that is worth saying plainly. This API renders HTML to PDF. By the time markup reaches it, every value in it is already a string that somebody's code produced, so there is no locale option on the render because there would be nothing for one to do. What the render controls is the page: the size, the margins, and whether the formatted value still fits the column it landed in. That is why each of these pages has a paragraph about the layout consequence, because that is the half a document adds to the general problem.
Frequently asked
Should the document use the sender's conventions or the reader's?
That is a decision rather than a fact, and the only wrong answer is not making it. The issuer's conventions are defensible for a document that is a record of what the issuer did. The recipient's are defensible for a document meant to be acted on. What fails is a document that mixes them, because a reader who sees two conventions on one page cannot tell which one any given figure is in.
Is it enough to set the document language?
No. A language attribute helps with hyphenation, with the assistive technology reading order and with anything that needs to know what language the text is in, and it changes none of the values. A date formatted as 03/04/2026 is exactly as ambiguous in a document declared as English as in one declared as anything else. The values are formatted upstream.
Why does this belong in a document reference rather than a general one?
Because a document cannot be re-rendered by its reader. On a screen a wrong format is annoying and a user can often change a setting. On paper the format is final, the layout was tuned to the string lengths of one language, and a value that grew by a few characters can push a table onto another page. The formatting problem and the pagination problem are the same problem here.
Related formatting topics
The defects that travel together, then the rest of the same group.
Address line order by country, and the postcode in the wrong place
Which lines an address has and what order they go in, both of which vary by destination and neither of which is a property of your database schema.
Tax and registration identifiers, and the validator that rejects them
Registration numbers whose length, character set and check rules differ by country, printed and validated by systems that assume the shape of the first country they supported.
Name order and the assumption that breaks a salutation
The assumption that a person has a given name followed by a family name, in that order, which is wrong often enough that a document built on it insults people regularly.
Contact details block, as a layout problem
The block this value lands in, and what it takes to make it fit.
Every formatting and locale topic
The full list, grouped by money, time, identity and generated language.
Writing systems in a PDF
The other half: whether the glyphs of a script come out shaped and joined correctly.
Values are formatted by your code before they reach the markup, so every fix on this page is upstream of the render. What the render decides is whether the result still fits.