DEV Community

Cover image for Visually spaced phone and IBAN numbers using HTML and CSS
Ingo Steinke
Ingo Steinke

Posted on

Visually spaced phone and IBAN numbers using HTML and CSS

How to display numbers that should be both human-readable and machine-readable? An international bank account number (IBAN) is a very long numeric code like DE89430609673029840000 which becomes hard to read for the human eye. The standard recommends to write blocks of four digits, so the number becomes DE89 4306 0967 3029 8400 00.

Human-Readable + Machine-Readable

But this human-readable block-of-four notation causes problems when people copy and paste the formatted bank code into an input fields that uses an HTML form field validation or a similar JavaScript evaluation which often does not accept spaces (which is a usability failure, but still common practice).

Screenshot of a validation error

Writing phone numbers causes a similar challenge. We want to present a correct international machine-readable phone number, linked as a tel: url, but which is also easy to read and memorize for our human customers at the same time!

CSS Adjacent Sibling Selector

Of course there is a solution using CSS, but we have to change our HTML markup as well, using <span>s for each visually separated block.

<span class="visually-spaced">DE89</span><span class="visually-spaced">4306</span><span class="visually-spaced">0967</span><span class="visually-spaced">3029</span><span class="visually-spaced">8400</span><span class="visually-spaced">00</span>
Enter fullscreen mode Exit fullscreen mode

We can now use ::before pseudo elements to add a visual space between the elements. Using the adjacent sibling selector (plus sign "+") there will be no space before the first block.

visually-spaced+.visually-spaced:before {
    content: " ";
    letter-spacing: .25rem;
}
Enter fullscreen mode Exit fullscreen mode

Now it looks like distinct blocks, but the content contains no white-space characters, so when we copy and paste the line of visually separated blocks, it becomes one single block without any separating characters in between.

Screenshot of selected bank account number and developer tools showing the markup explained above.

Continuous Underline

So far, we could have achieved the same effect using margin or padding without pseudo elements, or set a width on our pseudo elements, but when we want to link our formatted content and underline the link, the underline would be broken between the blocks.

Screenshot of formatting variations shown in the codepen

You can see the example above in this codepen.

Maintaining Developer Experience (DX)

So we used some CSS and HTML markup to improve our user experience (UX), but what about developer experience (DX)? Now our source code has become less readable so it has become harder to edit and maintain our code.

before:
DE89 4306 0967 3029 8400 00

after:
<span class="visually-spaced">DE89</span><span class="visually-spaced">4306</span><span class="visually-spaced">0967</span><span class="visually-spaced">3029</span><span class="visually-spaced">8400</span><span class="visually-spaced">00</span>
Enter fullscreen mode Exit fullscreen mode

But in 2022 we rarely edit our source code manually. Most content will be generated by some content management system (CMS) or site builder (like 11ty or another Jamstack tool).

Using liquid code to generate multiple language versions of my content, my before vs. after situation actually looks like this.

Before: print a localized content string

JSON:
  "bankaccountNumber": "DE89 4306 0967 3029 8400 00"
Enter fullscreen mode Exit fullscreen mode
Liquid:
{{ content.bankaccountNumber }}
Enter fullscreen mode Exit fullscreen mode

After: iterate over an array of strings

JSON:
  "bankaccountNumberChunks": [
    "DE89",
    "4306",
    "0967",
    "3029",
    "8400",
    "00"
  ],
Enter fullscreen mode Exit fullscreen mode
Liquid:
{%- for chunk in content.bankaccountNumberChunks -%}<span class="visually-spaced">{{ chunk }}</span>{%- endfor -%}            
Enter fullscreen mode Exit fullscreen mode

A practical example of this formatting technique can be found on my own website: www.ingo-steinke.com/#contact

Discussion (0)