Fontdue serves every font collection’s webfonts through a single CSS stylesheet of @font-face blocks.
For the higher-level view – how to embed the stylesheet, what the Webfonts tab is for, how to name styles for the shared-family selectors – see Webfonts.
Two selectors per style
Each style is reachable through two selectors, both emitted into the same stylesheet. The Webfonts tab on each font collection lists the CSS needed to select each of its styles or variable instances.
- A full-name selector keyed on
font-family: "Example Bold"atfont-weight: 400. Full names are unique by construction – two styles can’t share one – so this selector always works, regardless of how the family is shaped. - A shared-family selector keyed on
font-family: "Example"with the style’s realfont-weight,font-style, andfont-stretch. This is what lets a page set onefont-familyon a parent element and switch styles with the standard descriptors.
Websites can use either selector, but the shared-family form is the conventional way to write CSS for a font: set font-family: "Example" once and let font-weight: 700 or font-style: italic pick the right style.
The shared-family form is liable to collisions – when two or more styles share the same set of font-weight, font-style and font-stretch properties – in which case these selectors can’t select styles. The Webfonts tab shows this clearly with warnings, and allows you to resolve this by overriding the family names for each style11See Webfonts → Resolving shared-family warnings for the override tool that resolves collisions.. The alternative is to use the full-name selectors: each style has a unique font-family string, so a page that addresses styles by full name always works22Historically, only the full-name selectors were emitted by Fontdue’s webfont CSS.
Vertical metric overrides
Alongside the font src, Fontdue sets ascent-override, descent-override, and line-gap-override on every @font-face from the font’s hhea table so vertical spacing stays consistent across browsers33Fontdue reads from hhea specifically because Safari on Mac ignores the CSS overrides and always uses hhea. Other browsers read OS/2 typo metrics when the font’s useTypoMetrics flag is set (and fall back to hhea or Windows-specific win metrics otherwise), but they all honor the overrides – so applying hhea values as overrides in every @font-face aligns everyone on the same numbers..
Variable fonts
The Webfonts tab lists the CSS required to select each named instance in a variable font, and Fontdue emits appropriate @font-face and CSS selectors for variable fonts using registered axes wght, wdth, slnt (ranges of font-weight, font-stretch and font-style: oblique)44The slnt axis maps to font-style: oblique <angle>deg, which Fontdue emits per the CSS and OpenType specs. Safari has a long-standing bug where oblique <angle>deg doesn’t apply the slant – to support it there, set the axis directly with font-variation-settings, noting that the slnt coordinate is the negation of the CSS oblique angle (oblique 14deg → "slnt" -14). See Arrow Type’s slnt-axis browser test. – ital and opsz are handled uniquely:
ital axis
For a variable font whose italics live on a binary ital axis (0 for upright, 1 for italic), Fontdue allows selecting the italics with font-style: italic appropriately.55Fontdue makes this work by emitting a second @font-face block alongside the main one, keyed on the same shared family but with font-style: italic and font-variation-settings: "ital" 1 baked in. This fixes browser inconsistencies – Chrome doesn’t normally map font-style: italic onto the ital axis..
opsz axis
CSS doesn’t have a selector for optical sizing, it’s intended to be automatic. The font-optical-sizing property defaults to auto, and sets the opsz axis from the rendered font-size automatically.
The selectors in the Webfonts tab leans on that default. The behavior depends on how a font uses opsz across its named instances:
- When every named instance carries the same
opszcoordinate, Fontdue treats the value as a placeholder and omitsopszvalues.66This lines up with how macOS handlesopsz: Core Text enables optical sizing “if there are no named instances that set opsz to a non-default value.” - When the named instances each pin
opszto a different value (e.g. one instance at 6 for Caption, another at 12 for Text, another at 48 for Display), Fontdue adds the coordinates infont-variation-settingsfor each instance. In that case the instance names are the optical-size selectors, and the named-instance CSS has to set them.
The automatic setup is the more flexible one – rendered sizes between the named ones still get the appropriate optical setting, and a web page can change font-size without overriding the optical sizing. See Variable fonts → Webfont CSS for the export-side recommendation.
Custom axes
Anything beyond wght/wdth/slnt/ital/opsz has no standard CSS descriptor, so Fontdue carries pinned coordinates through to each instance’s font-variation-settings declaration.
Color fonts
For a color font uploaded in multiple techs, the @font-face src declaration lists one entry per (file, tech) with CSS tech() hints, in preference order COLRv1 → COLRv0 → SVG → sbix → CBDT. The browser picks the first entry it can render. See Color fonts → On the web for the example block.
hhea specifically because Safari on Mac ignores the CSS overrides and always uses hhea. Other browsers read OS/2 typo metrics when the font’s useTypoMetrics flag is set (and fall back to hhea or Windows-specific win metrics otherwise), but they all honor the overrides – so applying hhea values as overrides in every @font-face aligns everyone on the same numbers. ↩slnt axis maps to font-style: oblique <angle>deg, which Fontdue emits per the CSS and OpenType specs. Safari has a long-standing bug where oblique <angle>deg doesn’t apply the slant – to support it there, set the axis directly with font-variation-settings, noting that the slnt coordinate is the negation of the CSS oblique angle (oblique 14deg → "slnt" -14). See Arrow Type’s slnt-axis browser test. ↩@font-face block alongside the main one, keyed on the same shared family but with font-style: italic and font-variation-settings: "ital" 1 baked in. This fixes browser inconsistencies – Chrome doesn’t normally map font-style: italic onto the ital axis. ↩opsz: Core Text enables optical sizing “if there are no named instances that set opsz to a non-default value.” ↩