Proportional vs. Monospaced Numbers: When to use which one in order to avoid “Wiggling Labels”

Lior Azi
5 min readFeb 9, 2018

--

Definition

Proportional font is a font where each character occupies only as much width as it needs.
Monospaced font (also called a fixed-pitch, fixed-width, tabular, or non-proportional font) is a font where each character occupies the same amount of space on a horizontal line of text.

proportional font — a proportional width to each character
monospaced font — each character occupies the same width space

The Problem

The use of a proportional font in a dynamic label (with animated digits) causes a horizontal wiggling of the label (as in the second row of the example below) due to the fact the whole label’s width is changing all the time.
This wiggling highly hurts the user experience.
It causes the user’s eye to lose focus of the number change, due to the rapidly changes of the whole label horizontally, which creates a discomfort that must be avoided.

(1) Monospaced numbers are more appropriate for dynamic labels (with animation)

When should you use each one

The main consideration of when to use each type of font is whether the text will be displayed in a dynamic label or static label.

Dynamic label

With a dynamic label we usually mean a label with numbers that will be animating due to a text change, f.e:

  • File size label while it is downloaded (see in the example¹ above)
  • Time elapsed/remaining in video/music players²
  • Call time elapsed
  • Stopwatch³

In these cases we should use monospaced numbers, which will help us avoiding those wiggling labels

Static label

In a static label, label with text which is not changed frequently, we’ll prefer to use the proportional font, f.e:

  • Date label
  • Phone number label
  • Email address label
  • URL address label

In these cases we should use proportional numbers.

Good Real World Examples 👏🏻

  • iOS Music App
(2) iOS 11 Music App
  • iOS Clock App Stopwatch
(3) iOS11 Clock App Stopwatch

“Bad” Real World Examples 😔

Web

  • F̶a̶c̶e̶b̶o̶o̶k̶ ̶W̶e̶b̶ ̶V̶i̶d̶e̶o̶ P̶l̶a̶y̶e̶r̶
Facebook Video playing on Chrome for MacOS

(reported a problem to fb)

Desktop Apps

  • G̶o̶o̶g̶l̶e̶ ̶C̶h̶r̶o̶m̶e̶ ̶B̶r̶o̶w̶s̶e̶r̶ (Fixed on v65!)
Google Chrome Browser for MacOS (v64.0.3282.119)
  • A̶p̶p̶l̶e̶ ̶S̶a̶f̶a̶r̶i̶
Apple Safari Downloads (v11.0)

(filed a radar — rdar://37368720)

Spotify macOS app Elapsed time in Player (v1.0.75.483)

Mobile

  • T̶w̶i̶t̶t̶e̶r̶ ̶i̶O̶S̶ ̶A̶p̶p̶ ̶(̶F̶u̶l̶l̶-̶s̶c̶r̶e̶e̶n̶ ̶v̶i̶d̶e̶o̶ ̶p̶l̶a̶y̶e̶r̶)̶
Twitter iOS App Full-screen video player
  • V̶L̶C̶ ̶P̶l̶a̶y̶e̶r̶ ̶f̶o̶r̶ ̶i̶O̶S̶
VLC Player for iOS (v2.9)

TV

  • World Cup Qualifiers Basketball TV Graphics 24-Shot Clock
WC Qualifiers TV Graphics 24-Shot Clock (3rd from the left)

The Solution

As described in the text above, the solution is relatively easy.
In the all of the above “bad” examples a proportional font is used in dynamic labels, so the fix is simply to either enable monospaced digits in your current, or to change to another font supports monospaced digits.

iOS

Using Monospaced Digits in iOS
Since iOS9 the system font default display setting of numbers was changed from monospaced numbers to proportional numbers. It was probably changed because Apple figured out its the more frequent setting between the two.
In cases where a monospaced font is more appropriate the developer will need to opt-in to it:

If you’re using the system font (“San Francisco”) you can use the following code:

myLabel.font = UIFont.monospacedDigitSystemFont(ofSize: 42.0, weight: UIFontWeightMedium)

If you’re looking for a more generic solution, you should use the following font extension (Swift 4):

and then just use it with:

myLabel.font = myLabel.font.monospacedDigitFont

Note: The above extension will only work if your font is supporting the monospaced digits feature. If it doesn’t, consider using another font that does, or a monospaced font.(in iOS: “Courier” & “Menlo” are monospaced fonts)

SwiftUI

Using the monospacedDigit font modifier:

System font -

Text("0123456789")   .monospacedDigit()

Custom font -

Text("0123456789")   .font(.custom("Custom-Font-Name", size: 20.0))
.monospacedDigit()

React Native

<Text style={{fontVariant: 'tabular-nums'}}>
...
</Text>

Web

Using CSS:

.yourcssclass {
font-variant-numeric: tabular-nums;
}

Wrap Up

So the next time you’re adding a label with digits, whether it’s for TV, Web or Mobile, pay attention if it is dynamic or static, and set the font to be monospaced or proportional accordingly. That will help you avoid label wiggling, which will improve your app/website’s overall experience.

Update(11/4/2021): Facebook Web Video Played is now fixed! 🎉 🎉🎉.
VLC Player is now fixed!👏🏻👏🏻👏🏻

Update(6/25/2019): Added SwiftUI to iOS

Update(4/18/2019): Twitter Mobile App for iOS has fixed the issue! 🎉 🎉Apple Safari has fixes the issue on v12.0! 🎊🎊🎊

Update(3/15/2018): Google Chrome just fixed the issue on the latest macOS version — v65.0.3325.162, 👏🏻👏🏻👏🏻

Update(3/4/2018): Added React Native & Web solutions

Update(2/21/2018): Added extension solution to iOS

References:

This story is published in Noteworthy, where 10,000+ readers come every day to learn about the people & ideas shaping the products we love.

Follow our publication to see more product & design stories featured by the Journal team.

--

--

Lior Azi

Mobile Engineer • UX Addict • Music Enthusiastic