ankidroid / ankidroid/Anki-Android

MathJax √ radical bar has vertical+horizontal gap from √ glyph (AnkiDroid only; MathJax 3 CHTML)

Ouverte
#20,776 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
upstream-issue
Langage dominant
Kotlin
Étoiles
11.8k
Forks
2.9k
Merge moyen
2 j 3 h
PR mergées (30 j)
171

Description

### Checked for duplicates?
- [x] Most related prior issue is #9002 (closed 2021) but that was about general MathJax rendering differences. This one is specifically about the √ radical bar not connecting to the √ glyph.
- Related forum thread (no resolution, auto-closed): [MathJax looks bunched up](https://forums.ankiweb.net/t/mathjax-looks-bunched-up/68438) — same class of symptom (MathJax HTML renderer quirks on AnkiDroid vs Desktop). Moderator characterizes these as MathJax HTML renderer issues rather than AnkiDroid-specific, which is consistent with the diagnosis below.

### Does it also happen in the desktop version?
- [x] Does NOT occur on Anki Desktop (Qt WebEngine). Only AnkiDroid (Android WebView).

### Steps to reproduce
1. Create a card with `\( \sqrt{a^2} \)` (or any `\sqrt{...}`)
2. View on AnkiDroid and on Anki Desktop side by side

### Expected
Horizontal bar of √ touches the top-right of the √ glyph, as on Desktop.

### Actual
On AnkiDroid, the bar sits a few px above the √ tail and a few px right of where it should meet the glyph tip. A visible gap appears between the glyph and the bar.

### Screenshot

| Before (no fix — visible gap) | After (with CSS workaround) |
|---|---|
| before | after |

### Diagnosis (via chrome://inspect)
- MathJax: **3.2.2**, CHTML output (`jax="CHTML"`)
- DOM structure: `` — the bar is `border-top` of `mjx-box`
- `surd.top === box.top` and `surd.right === box.left` per `getBoundingClientRect()` → **layout is 0-gap, the gap is purely visual**
- Computed `border-top`: `~2.78px solid currentColor`
- Fonts `MJXZERO` and `MJXTEX` both `loaded` — no font-loading race
- Root cause: MJX-TEX font's **glyph bearing** (blank space inside the √ character's em box) is rasterized with more offset by Android WebView than by Qt WebEngine. MathJax 3 places the bar at the top of the em box; when the glyph's visible top is below that, a gap appears.

### Additional notes on MathJax 2 config dead code
Many card templates carry legacy
```html

MathJax.Hub.Config({ "HTML-CSS": { preferredFont: "Noto Sans Math", webFont: "Noto Sans Math", ... } });

```
blocks. These are silently ignored by MathJax 3 (and any CSS `@font-face` / `mjx-c { font-family: ... }` overrides cause metrics mismatches with MJX-TEX's internal metric tables). Not a bug — just something that newcomers will find confusing.

### Workaround (tested, works)

CSS on the affected note types:
```css
html.mobile-webview mjx-sqrt > mjx-box {
margin-top: 3px !important;
margin-left: -3px !important;
}
```

Tiny UA-detect script at the top of each Front template:
```html
if(/Android|iPhone|iPad|iPod/i.test(navigator.userAgent))document.documentElement.classList.add("mobile-webview");
```

**Important:** `@media (hover: none) and (pointer: coarse)` does **not** match on AnkiDroid WebView (confirmed via `matchMedia(...).matches === false`), so a simple media query won't work — the UA-based class is needed.

The `3px / -3px` values are a compromise — the required offset varies slightly per card because MathJax uses different √ size variants (MJXTEX-S1..S4) for different radicand heights.

### Expected resolution path
Likely fixed by upstream Anki's adoption of MathJax 4, which allows switching to `mathjax-newcm` or `mathjax-stix2` fonts — different fonts may not have the same bearing mismatch in Android WebView.

Tracking upstream:
- ankitects/anki#4277 — Investigate MathJax 4.0 ([link](https://github.com/ankitects/anki/issues/4277))
- ankitects/anki#4464 — Update MathJax to v4.0.0 ([link](https://github.com/ankitects/anki/pull/4464)) — PR is open, CI passes, but currently blocked on CSP (MathJax 4 dynamically loads font data from `cdn.jsdelivr.net` which is refused by Anki's WebView CSP).

### Debug info
AnkiDroid 2.23.3 (or current), Android WebView (Chromium-based). Reproduces on multiple Android versions.

---

Filing for visibility / as a test case. No urgent fix needed — local workaround works. Feel free to close as wontfix or dupe-of-mathjax-4-migration if appropriate.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.