ankidroid / ankidroid/Anki-Android

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

Abierto
#20,776 3 comentarios 0 reacciones 0 asignados Ver en GitHub
upstream-issue
Lenguaje dominante
Kotlin
Estrellas
11.8k
Forks
2.9k
Merge medio
2 d 3 h
PR fusionados (30 d)
171

Descripción

### 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)

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.