Signal

Font preferences

We sample default font-stack rendering metrics. Engine-bound — captures what the browser plus OS choose as defaults for each generic family.

Reviewed

Tier 1 engine

What it measures

Each call records the integer offsetWidth of a fixed test string rendered in a hidden off-screen container across a small set of CSS generic family keywords, plus a minimum-font-size policy probe.

The generic-family measurements capture which actual font the browser substitutes for each CSS keyword. On the same machine, Safari resolves sans-serif to Helvetica, Chrome on macOS resolves it to Arial, Firefox on Linux to DejaVu Sans. The minimum-font-size probe catches users with accessibility minimum font size settings configured; when enforced, a small span is clamped to the floor and its rendered width balloons.

Complementary to the fonts signal

The fonts signal probes a curated detect list to answer 'which named fonts are installed?'. Font preferences captures what the OS and browser have chosen as defaults for each CSS generic family. Distinct entropy axis: fonts answers 'which named fonts exist?' while font preferences answers 'what does your sans-serif render as?'

Width only. Height is dropped per the design constraint. Sub-pixel glyph-positioning jitter makes offsetHeight unstable across calls on the same engine; offsetWidth is rock solid because it's an integer sum of glyph advance widths.

Confidence rules

ConfidenceTrigger
normaldocument and document.body available; all measurements collected
absentdocument is undefined (non-browser runtime) or document.body is null

Things worth knowing

  • Apple-only system family keywords return the baseline width on non-Apple browsers (the family doesn't resolve to anything). The differential between Apple and non-Apple values is the entropy point.
  • Brave Standard Shields farbles widths per-eTLD+1, but the farbling is deterministic per origin, so the hash stays stable across calls on the same site.
  • Firefox resistFingerprinting returns a fixed set of widths consistent across all Firefox-resist installs. Entropy collapses but the signal stays normal.
  • Dynamic Type on iOS Safari: the system body width shifts when the user changes their iOS Dynamic Type accessibility setting. Real entropy, but it means the hash changes after a user adjusts accessibility — an unavoidable trade-off.
  • Hidden off-screen container is removed in a finally block. No DOM leak even on exceptions.
  • The exact families probed, the test string, the font sizes used, and the per-call measurement count are deliberately not published. Treat the result shape and confidence as the stable interface.

Last reviewed 2026-06-04