Portrait of Marc Bouchenoire Typometerv2.1.2

Typometer

Measure text asynchronously.

  • 🗜️ Small: Just around 1 kB on modern platforms
  • ⚡️ Multi-threaded: Run from a Worker when OffscreenCanvas is supported
  • 🧪 Reliable: Fully tested with 100% code coverage
  • 📦 Typed: Written in TypeScript and includes definitions out-of-the-box
  • 💨 Zero dependencies
View on GitHub
/
{
  "actualBoundingBoxAscent": 0,
  "actualBoundingBoxDescent": 0,
  "actualBoundingBoxLeft": 0,
  "actualBoundingBoxRight": 0,
  "fontBoundingBoxAscent": 0,
  "fontBoundingBoxDescent": 0,
  "width": 0
}
Size16px
Weight400
Family"sans-serif"
Style"normal"

Introduction

Measuring text performantly in the browser isn't as straightforward as one would think—the recommended way is to leverage the Canvas API (and its measureText method) instead of relying on the DOM directly. Typometer embraces this way into a single function and attempts to smooth out the differences between the DOM and the Canvas API.

When supported, Typometer will leverage an OffscreenCanvas from a Worker to measure in a background thread.

Name

Typometer is named after a physical ruler used to measure in typographic points.

Installation

Skypack

import { typometer } from "https://cdn.skypack.dev/typometer"

Yarn

yarn add typometer

npm

npm install typometer

Usage

Import typometer.

import { typometer } from "typometer"

Invoke it asynchronously with a string and access serialized TextMetrics in return.

const metrics = await typometer("With impressions chosen from another time.")

// metrics: {
//   actualBoundingBoxAscent: 8,
//   actualBoundingBoxDescent: 3,
//   actualBoundingBoxLeft: 0,
//   actualBoundingBoxRight: 195.0732421875,
//   alphabeticBaseline: 0,
//   emHeightAscent: 10,
//   emHeightDescent: 2,
//   fontBoundingBoxAscent: 10,
//   fontBoundingBoxDescent: 2,
//   hangingBaseline: 10,
//   ideographicBaseline: -2,
//   width: 195.0732421875
// }

Given an array of strings instead, typometer will return an array of serialized TextMetrics.

const metrics = await typometer([
  "With impressions chosen from another time.",
  "Underneath a sky that's ever falling down."
])

// metrics: [TextMetrics, TextMetrics]

Options

Font

A secondary argument can be set to specify a font appearance—from properties, a font string, or a CSSStyleDeclaration.

Properties

Specify individual font properties as an object with fontFamily, fontSize, fontStretch, fontStyle, fontVariant, fontWeight, and lineHeight.

const metrics = await typometer("", {
  fontFamily: "cursive",
  fontSize: 16,
  fontStyle: "italic",
  fontWeight: 500,
  fontVariant: "small-caps",
  lineHeight: 2
})
string

Specify all font properties as a font shorthand string.

const metrics = await typometer("", "italic small-caps 500 16px/2 cursive")
CSSStyleDeclaration

Specify a CSSStyleDeclaration from which to extract font properties.

const paragraph = document.querySelector("p")
const metrics = await typometer("", window.getComputedStyle(paragraph))