Skip to content

fix: load a real bold weight instead of synthesizing it - #181

Closed
magnus-madsen wants to merge 2 commits into
masterfrom
fix/real-font-weights
Closed

fix: load a real bold weight instead of synthesizing it#181
magnus-madsen wants to merge 2 commits into
masterfrom
fix/real-font-weights

Conversation

@magnus-madsen

Copy link
Copy Markdown
Member

Only Open Sans 400 was loaded. Verified against the built CSS before the change:

total @font-face blocks: 10
  10x  Open Sans @ 400

Meanwhile the site asks for weight 700 in 56 places (.font-weight-bold ×16, <b> ×21, <strong> ×6, plus Bootstrap's .font-weight-bold{font-weight:700!important}), and Bootstrap sets h1..h6{font-weight:500}.

A browser can't fail this request, so it synthesizes the bold — dilating the 400 outlines uniformly. Counters close up, stroke colour goes uneven against surrounding text, and each engine smears differently, so bold looked different per visitor. Headings at 500 hit the other path: no synthesis, silent fallback to 400, so every heading rendered lighter than designed.

Change

Swap the single static weight for the variable font, covering 300–800 in one file per subset:

import '@fontsource-variable/open-sans';

The variable package declares the family as 'Open Sans Variable', not 'Open Sans' — so global.css is updated to match. Without that the font would silently stop applying and everything would fall back to sans-serif. The old name is kept as a fallback.

Cost

The latin subset grows 18.6 KB → 48.3 KB. For comparison, static 400 + 700 would be ~38 KB and would still leave headings without their 500. Woff2 is cached across all pages.

Italic is not included. The site has 25 italic usages that are currently synthesized too, but the italic face is another 50 KB, which is poor value for decorative emphasis. One import adds it later if wanted.

Verification

after:  10x  Open Sans Variable | weight 300 800 | normal
body font-family, last rule wins -> Open Sans Variable,Open Sans,sans-serif
  • npm run check — 0 errors, 0 warnings, 0 hints
  • npm run build — clean, 10 pages
  • Confirmed global.css orders after Bootstrap in the bundle, so the family actually applies

🤖 Generated with Claude Code

magnus-madsen and others added 2 commits August 3, 2026 14:45
Only Open Sans 400 was loaded, but the site asks for weight 700 in 56
places and Bootstrap sets headings to 500. Browsers cannot fail here, so
they synthesize: the 400 outlines get dilated, closing up counters and
rendering differently in every engine. Headings fell back to 400 and so
rendered lighter than intended.

Swap the single static weight for the variable font, which covers
300-800 in one file per subset. Bold and heading weights are now real
outlines. The family name differs ('Open Sans Variable'), so global.css
is updated to match, keeping the static name as a fallback.

Latin subset grows from 18.6 KB to 48.3 KB. Two static weights would
cost ~38 KB and still leave headings without their 500.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bootstrap sets h1-h6 to 500. That never rendered before, because only
weight 400 was loaded, so headings silently fell back to regular. Now
that the variable font supplies 500 the rule takes effect and headings
read heavier than they used to. Pin them back to 400.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@magnus-madsen
magnus-madsen deleted the fix/real-font-weights branch August 3, 2026 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant