Skip to content

feat(css): provide katex-swap.css that uses font-display: swap - #3940

Merged
edemaine merged 12 commits into
KaTeX:mainfrom
FreyaHolmer:patch-1
Oct 13, 2025
Merged

edemaine merged 12 commits into
KaTeX:mainfrom
FreyaHolmer:patch-1

Conversation

@FreyaHolmer

Copy link
Copy Markdown
Contributor

Google fonts seem to default to swap, and mixing them with katex makes it so that katex is invisible briefly on page load, unlike google fonts which make use of fallbacks while loading. This would unify their behavior.

Ideally there'd be an option for this, and a ?display=swap in the cdn url (like google fonts: https://developers.google.com/fonts/docs/css2#use_font-display), but I don't know if jsdelivr supports that!

What is the previous behavior before this PR?
Katex fonts would be invisible until loaded

What is the new behavior after this PR?
Katex fonts will now render a fallback until fonts have been loaded

BREAKING CHANGE: changes font loading behavior to font-display: swap,
which means equations will render a fallback before loaded
instead of being invisible

Closes #2242

Google fonts seem to default to swap, and mixing them with katex makes it so that katex is invisible briefly on page load, unlike google fonts which make use of fallbacks while loading. This would unify their behavior.

Ideally there'd be an option for this, and a ?display=swap in the cdn url (like google fonts: https://developers.google.com/fonts/docs/css2#use_font-display), but I don't know if jsdelivr supports that!
@FreyaHolmer FreyaHolmer changed the title fix(css): fefault to font-display: swap; closes #2242 fix(css): Default to font-display: swap; closes #2242 Mar 21, 2024
@yao-genius

Copy link
Copy Markdown

Why hasn't this fix been approved yet? I had the same problem.

@edemaine

edemaine commented Oct 8, 2024

Copy link
Copy Markdown
Member

This PR needs to be ported from less to scss, though I suspect that would be easy. There's also a question of what's the best default.

Actually, we could offer multiple .css builds with different settings. I think block and swap are the two natural choices here, depending on whether you want to flash empty content (current behavior I guess) or flash incorrectly styled content.

@edemaine edemaine changed the title fix(css): Default to font-display: swap; closes #2242 feat(css): provide katex-swap.css that uses font-display: swap Dec 8, 2024

@edemaine edemaine left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for submitting this, and apologies for the long delay.

I modified the PR to work as follows:

  • katex.css and katex.min.css use font-display: block, roughly the same as before. I believe this is still a useful configuration to avoid "flash of unstyled text" (FOUT), but instead have "flash of invisible content" (FOIT) (more info).
    • In particular, I hesitate to modify the default here, because so many people use KaTeX and this might be a significant deviation from expected behavior.
  • katex-swap.css and katex-swap.min.css use font-display: swap to enable "flash of unstyled text" (FOIT) instead of "flash of invisible content" (FOUT)
  • Variable $font-display is still overridable (now via SCSS instead of Less)

TLDR: if you want font-display: swap, you use katex-swap.css instead of katex.css. But default remains roughly the same.

I'd appreciate any feedback on this approach (from original poster or anyone else interested in this feature) before merging.

@grigoriy-reshetniak

Copy link
Copy Markdown
Member

Hello @edemaine.
I've discovered this PR while browsing open ones and I feel like it's a shame it hadn't been merged. Looking from the OP's perspective:

Ideally there'd be an option for this

I think since your changes actually provided that option this PR deserves to be merged.

@edemaine

Copy link
Copy Markdown
Member

Thanks Grigoriy! That's the feedback/confirmation I was looking for. I'll merge it.

@edemaine
edemaine enabled auto-merge (squash) October 13, 2025 02:58
@edemaine
edemaine merged commit b3f9ce6 into KaTeX:main Oct 13, 2025
8 checks passed
KaTeX-bot added a commit that referenced this pull request Oct 13, 2025
## [0.16.25](v0.16.24...v0.16.25) (2025-10-13)

### Features

* **css:** provide `katex-swap.css` that uses `font-display: swap` ([#3940](#3940)) ([b3f9ce6](b3f9ce6)), closes [#2242](#2242)
@KaTeX-bot

Copy link
Copy Markdown
Member

🎉 This PR is included in version 0.16.25 🎉

The release is available on:

Your semantic-release bot 📦🚀

dadezzz pushed a commit to dadezzz/university_notes that referenced this pull request May 26, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [katex](https://katex.org) ([source](https://github.com/KaTeX/KaTeX)) | [`0.16.47` → `0.17.0`](https://renovatebot.com/diffs/npm/katex/0.16.47/0.17.0) | ![age](https://developer.mend.io/api/mc/badges/age/npm/katex/0.17.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/katex/0.16.47/0.17.0?slim=true) |

---

### Release Notes

<details>
<summary>KaTeX/KaTeX (katex)</summary>

### [`v0.17.0`](https://github.com/KaTeX/KaTeX/blob/HEAD/CHANGELOG.md#0170-2026-05-22)

[Compare Source](KaTeX/KaTeX@v0.16.47...v0.17.0)

##### Performance Improvements

- simplify `defineFunction` to avoid destructuring, improve typing ([#&#8203;4222](KaTeX/KaTeX#4222)) ([fb604e6](KaTeX/KaTeX@fb604e6))

##### BREAKING CHANGES

- The internal API for `__defineFunction` changed: you should no longer wrap properties in `props`.

#### [0.16.47](KaTeX/KaTeX@v0.16.46...v0.16.47) (2026-05-16)

##### Bug Fixes

- correct size of `[` big delimiter ([#&#8203;4217](KaTeX/KaTeX#4217)) ([7ba0027](KaTeX/KaTeX@7ba0027)), closes [#&#8203;4215](KaTeX/KaTeX#4215)

#### [0.16.46](KaTeX/KaTeX@v0.16.45...v0.16.46) (2026-05-13)

##### Bug Fixes

- preserve math font in some styling commands ([#&#8203;4214](KaTeX/KaTeX#4214)) ([e9ee046](KaTeX/KaTeX@e9ee046)), closes [#&#8203;4213](KaTeX/KaTeX#4213)

#### [0.16.45](KaTeX/KaTeX@v0.16.44...v0.16.45) (2026-04-05)

##### Bug Fixes

- wrap vcenter mpadded in mrow for valid MathML ([#&#8203;4193](KaTeX/KaTeX#4193)) ([ee66b78](KaTeX/KaTeX@ee66b78)), closes [#&#8203;4078](KaTeX/KaTeX#4078)

#### [0.16.44](KaTeX/KaTeX@v0.16.43...v0.16.44) (2026-03-27)

##### Bug Fixes

- remove extra \jot space at bottom of align/gather/etc. ([#&#8203;4184](KaTeX/KaTeX#4184)) ([3870ee9](KaTeX/KaTeX@3870ee9))

#### [0.16.43](KaTeX/KaTeX@v0.16.42...v0.16.43) (2026-03-26)

##### Bug Fixes

- use makeEm() consistently to truncate long CSS decimals ([#&#8203;4181](KaTeX/KaTeX#4181)) ([0967dcc](KaTeX/KaTeX@0967dcc))

#### [0.16.42](KaTeX/KaTeX@v0.16.41...v0.16.42) (2026-03-24)

##### Features

- \underbracket and \overbracket ([#&#8203;4147](KaTeX/KaTeX#4147)) ([5be9abb](KaTeX/KaTeX@5be9abb))

#### [0.16.41](KaTeX/KaTeX@v0.16.40...v0.16.41) (2026-03-24)

##### Bug Fixes

- \sout in text mode ([#&#8203;4173](KaTeX/KaTeX#4173)) ([e748578](KaTeX/KaTeX@e748578))

#### [0.16.40](KaTeX/KaTeX@v0.16.39...v0.16.40) (2026-03-20)

##### Bug Fixes

- **css:** specify position: relative for .katex ([#&#8203;4170](KaTeX/KaTeX#4170)) ([020f0d8](KaTeX/KaTeX@020f0d8))

#### [0.16.39](KaTeX/KaTeX@v0.16.38...v0.16.39) (2026-03-19)

##### Bug Fixes

- middle dot in text mode ([#&#8203;4169](KaTeX/KaTeX#4169)) ([edb45b0](KaTeX/KaTeX@edb45b0)), closes [#&#8203;3641](KaTeX/KaTeX#3641)

#### [0.16.38](KaTeX/KaTeX@v0.16.37...v0.16.38) (2026-03-08)

##### Bug Fixes

- accent skew mixed with font specifiers ([#&#8203;4159](KaTeX/KaTeX#4159)) ([aea3375](KaTeX/KaTeX@aea3375)), closes [#&#8203;4121](KaTeX/KaTeX#4121)

#### [0.16.37](KaTeX/KaTeX@v0.16.36...v0.16.37) (2026-03-06)

##### Bug Fixes

- negative-width `\hphantom` and symmetric `\smash` ([#&#8203;4153](KaTeX/KaTeX#4153)) ([d4799ca](KaTeX/KaTeX@d4799ca))

#### [0.16.36](KaTeX/KaTeX@v0.16.35...v0.16.36) (2026-03-06)

##### Bug Fixes

- contrib esm bloat ([#&#8203;4157](KaTeX/KaTeX#4157)) ([2bde1ad](KaTeX/KaTeX@2bde1ad))

#### [0.16.35](KaTeX/KaTeX@v0.16.34...v0.16.35) (2026-03-05)

##### Bug Fixes

- version number regression ([#&#8203;4155](KaTeX/KaTeX#4155)) ([db26b73](KaTeX/KaTeX@db26b73))

#### [0.16.34](KaTeX/KaTeX@v0.16.33...v0.16.34) (2026-03-05)

##### Bug Fixes

- emoji with variation selector ([#&#8203;4151](KaTeX/KaTeX#4151)) ([c2606e5](KaTeX/KaTeX@c2606e5))

#### [0.16.33](KaTeX/KaTeX@v0.16.32...v0.16.33) (2026-02-23)

##### Bug Fixes

- **scss:** forward variables to fonts module ([#&#8203;4146](KaTeX/KaTeX#4146)) ([9349a64](KaTeX/KaTeX@9349a64))

#### [0.16.32](KaTeX/KaTeX@v0.16.31...v0.16.32) (2026-02-22)

##### Bug Fixes

- italic separation in \mathnormal ([#&#8203;4143](KaTeX/KaTeX#4143)) ([71305a0](KaTeX/KaTeX@71305a0))

#### [0.16.31](KaTeX/KaTeX@v0.16.30...v0.16.31) (2026-02-22)

##### Bug Fixes

- `\*frac` sizing ([#&#8203;4137](KaTeX/KaTeX#4137)) ([ef51f18](KaTeX/KaTeX@ef51f18))

#### [0.16.30](KaTeX/KaTeX@v0.16.29...v0.16.30) (2026-02-22)

##### Bug Fixes

- no line breaks after `\not` ([#&#8203;4140](KaTeX/KaTeX#4140)) ([2d1ba86](KaTeX/KaTeX@2d1ba86))

#### [0.16.29](KaTeX/KaTeX@v0.16.28...v0.16.29) (2026-02-22)

##### Bug Fixes

- `\imath` and other `\html@mathml` macros in arguments ([#&#8203;4139](KaTeX/KaTeX#4139)) ([a850cce](KaTeX/KaTeX@a850cce))

#### [0.16.28](KaTeX/KaTeX@v0.16.27...v0.16.28) (2026-01-25)

##### Bug Fixes

- **type:** add missing types definition path to package.json ([#&#8203;4125](KaTeX/KaTeX#4125)) ([0ef8921](KaTeX/KaTeX@0ef8921))

#### [0.16.27](KaTeX/KaTeX@v0.16.26...v0.16.27) (2025-12-07)

##### Features

- support equals sign and surrounding whitespace in \htmlData attribute values ([#&#8203;4112](KaTeX/KaTeX#4112)) ([c77aaec](KaTeX/KaTeX@c77aaec))

#### [0.16.26](KaTeX/KaTeX@v0.16.25...v0.16.26) (2025-12-07)

##### Bug Fixes

- \mathop followed by integral symbol ([6fbad18](KaTeX/KaTeX@6fbad18))

#### [0.16.25](KaTeX/KaTeX@v0.16.24...v0.16.25) (2025-10-13)

##### Features

- **css:** provide `katex-swap.css` that uses `font-display: swap` ([#&#8203;3940](KaTeX/KaTeX#3940)) ([b3f9ce6](KaTeX/KaTeX@b3f9ce6)), closes [#&#8203;2242](KaTeX/KaTeX#2242)

#### [0.16.24](KaTeX/KaTeX@v0.16.23...v0.16.24) (2025-10-12)

##### Features

- support hex colors with alpha ([#&#8203;4090](KaTeX/KaTeX#4090)) ([8c9b306](KaTeX/KaTeX@8c9b306)), closes [#&#8203;4067](KaTeX/KaTeX#4067) [#fA6](https://github.com/KaTeX/KaTeX/issues/fA6) [#fA6f1](https://github.com/KaTeX/KaTeX/issues/fA6f1)

#### [0.16.23](KaTeX/KaTeX@v0.16.22...v0.16.23) (2025-10-03)

##### Bug Fixes

- Support `\def` with arguments via `macros` option ([#&#8203;4087](KaTeX/KaTeX#4087)) ([80a8158](KaTeX/KaTeX@80a8158))

#### [0.16.22](KaTeX/KaTeX@v0.16.21...v0.16.22) (2025-04-09)

##### Bug Fixes

- \relax in base or exponent of super/subscript ([#&#8203;4045](KaTeX/KaTeX#4045)) ([1f43c84](KaTeX/KaTeX@1f43c84))

#### [0.16.21](KaTeX/KaTeX@v0.16.20...v0.16.21) (2025-01-17)

##### Bug Fixes

- escape \htmlData attribute name ([57914ad](KaTeX/KaTeX@57914ad))

#### [0.16.20](KaTeX/KaTeX@v0.16.19...v0.16.20) (2025-01-12)

##### Bug Fixes

- \providecommand does not overwrite existing macro ([#&#8203;4000](KaTeX/KaTeX#4000)) ([6d30fe4](KaTeX/KaTeX@6d30fe4)), closes [#&#8203;3928](KaTeX/KaTeX#3928)

#### [0.16.19](KaTeX/KaTeX@v0.16.18...v0.16.19) (2024-12-29)

##### Bug Fixes

- **types:** improve `strict` function type ([#&#8203;4009](KaTeX/KaTeX#4009)) ([4228b4e](KaTeX/KaTeX@4228b4e))

#### [0.16.18](KaTeX/KaTeX@v0.16.17...v0.16.18) (2024-12-18)

##### Bug Fixes

- Actually publish TypeScript type definitions ([#&#8203;4008](KaTeX/KaTeX#4008)) ([629b873](KaTeX/KaTeX@629b873))

#### [0.16.17](KaTeX/KaTeX@v0.16.16...v0.16.17) (2024-12-17)

##### Bug Fixes

- MathML combines multidigit numbers with sup/subscript, comma separators, and multicharacter text when outputting to DOM ([#&#8203;3999](KaTeX/KaTeX#3999)) ([7d79e22](KaTeX/KaTeX@7d79e22)), closes [#&#8203;3995](KaTeX/KaTeX#3995)

#### [0.16.16](KaTeX/KaTeX@v0.16.15...v0.16.16) (2024-12-17)

##### Features

- ESM exports, TypeScript types ([#&#8203;3992](KaTeX/KaTeX#3992)) ([ea9c173](KaTeX/KaTeX@ea9c173))

#### [0.16.15](KaTeX/KaTeX@v0.16.14...v0.16.15) (2024-12-09)

##### Features

- italic sans-serif in math mode via `\mathsfit` command ([#&#8203;3998](KaTeX/KaTeX#3998)) ([2218901](KaTeX/KaTeX@2218901))

#### [0.16.14](KaTeX/KaTeX@v0.16.13...v0.16.14) (2024-12-08)

##### Features

- \dddot and \ddddot support ([#&#8203;3834](KaTeX/KaTeX#3834)) ([bda35cd](KaTeX/KaTeX@bda35cd)), closes [#&#8203;2744](KaTeX/KaTeX#2744)

#### [0.16.13](KaTeX/KaTeX@v0.16.12...v0.16.13) (2024-12-08)

##### Bug Fixes

- `\vdots` and `\rule` support in text mode ([#&#8203;3997](KaTeX/KaTeX#3997)) ([0e08352](KaTeX/KaTeX@0e08352)), closes [#&#8203;3990](KaTeX/KaTeX#3990)

#### [0.16.12](KaTeX/KaTeX@v0.16.11...v0.16.12) (2024-12-08)

##### Features

- **css:** configurable margin for display math ([#&#8203;3638](KaTeX/KaTeX#3638)) ([3405001](KaTeX/KaTeX@3405001))

#### [0.16.11](KaTeX/KaTeX@v0.16.10...v0.16.11) (2024-07-02)

##### Features

- add \emph ([#&#8203;3963](KaTeX/KaTeX#3963)) ([9f34da4](KaTeX/KaTeX@9f34da4)), closes [#&#8203;3566](KaTeX/KaTeX#3566)

#### [0.16.10](KaTeX/KaTeX@v0.16.9...v0.16.10) (2024-03-24)

##### Bug Fixes

- \edef bypassing maxExpand via exponential blowup ([e88b4c3](KaTeX/KaTeX@e88b4c3))
- escape \includegraphics src and alt ([c5897fc](KaTeX/KaTeX@c5897fc))
- force protocol to be lowercase for better protocol filtering ([fc5af64](KaTeX/KaTeX@fc5af64)), closes [/datatracker.ietf.org/doc/html/rfc3986#section-3](https://github.com//datatracker.ietf.org/doc/html/rfc3986/issues/section-3)
- maxExpand limit with Unicode sub/superscripts ([085e21b](KaTeX/KaTeX@085e21b))

#### [0.16.9](KaTeX/KaTeX@v0.16.8...v0.16.9) (2023-10-02)

##### Features

- Support bold Fraktur ([#&#8203;3777](KaTeX/KaTeX#3777)) ([240d5ae](KaTeX/KaTeX@240d5ae))

#### [0.16.8](KaTeX/KaTeX@v0.16.7...v0.16.8) (2023-06-24)

##### Features

- expose error length and raw error message on ParseError ([#&#8203;3820](KaTeX/KaTeX#3820)) ([710774a](KaTeX/KaTeX@710774a))

#### [0.16.7](KaTeX/KaTeX@v0.16.6...v0.16.7) (2023-04-28)

##### Bug Fixes

- **docs/support\_table.md:** delete redundant "varPsi" ([#&#8203;3814](KaTeX/KaTeX#3814)) ([33a1b98](KaTeX/KaTeX@33a1b98))

#### [0.16.6](KaTeX/KaTeX@v0.16.5...v0.16.6) (2023-04-17)

##### Bug Fixes

- Support `\let` via `macros` option ([#&#8203;3738](KaTeX/KaTeX#3738)) ([bdb0be2](KaTeX/KaTeX@bdb0be2)), closes [#&#8203;3737](KaTeX/KaTeX#3737) [#&#8203;3737](KaTeX/KaTeX#3737)

#### [0.16.5](KaTeX/KaTeX@v0.16.4...v0.16.5) (2023-04-17)

##### Features

- \_\_defineFunction API exposing internal defineFunction ([#&#8203;3805](KaTeX/KaTeX#3805)) ([c7b1f84](KaTeX/KaTeX@c7b1f84)), closes [#&#8203;3756](KaTeX/KaTeX#3756)

#### [0.16.4](KaTeX/KaTeX@v0.16.3...v0.16.4) (2022-12-07)

##### Bug Fixes

- space should prevent optional argument to \ ([#&#8203;3746](KaTeX/KaTeX#3746)) ([a0deb34](KaTeX/KaTeX@a0deb34)), closes [#&#8203;3745](KaTeX/KaTeX#3745)

#### [0.16.3](KaTeX/KaTeX@v0.16.2...v0.16.3) (2022-10-22)

##### Bug Fixes

- \hline after \cr ([#&#8203;3735](KaTeX/KaTeX#3735)) ([ebf6bf5](KaTeX/KaTeX@ebf6bf5)), closes [#&#8203;3734](KaTeX/KaTeX#3734)

#### [0.16.2](KaTeX/KaTeX@v0.16.1...v0.16.2) (2022-08-29)

##### Bug Fixes

- **auto-render:** concatenate content of successive text nodes ([#&#8203;3422](KaTeX/KaTeX#3422)) ([4d3fdd8](KaTeX/KaTeX@4d3fdd8))
- Implement \pmb via CSS text-shadow ([#&#8203;3505](KaTeX/KaTeX#3505)) ([176552a](KaTeX/KaTeX@176552a))

#### [0.16.1](KaTeX/KaTeX@v0.16.0...v0.16.1) (2022-08-28)

##### Bug Fixes

- Use SVGs for some stacked delims ([#&#8203;3686](KaTeX/KaTeX#3686)) ([8a65a2e](KaTeX/KaTeX@8a65a2e))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTUuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE5NS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use font-display: swap to prevent invisible text on load

5 participants