Merge pull request #5411 from SHL0MS/fix/manim-monospace-fonts

fix(manim-video): recommend monospace fonts — proportional fonts have broken kerning
This commit is contained in:
SHL0MS
2026-04-06 00:36:19 -04:00
committed by GitHub
2 changed files with 32 additions and 22 deletions

View File

@@ -108,14 +108,18 @@ project-name/
### Fonts
Always specify fonts explicitly — the default renders poorly. See `references/visual-design.md` for full recommendations.
**Use monospace fonts for all text.** Manim's Pango renderer produces broken kerning with proportional fonts at all sizes. See `references/visual-design.md` for full recommendations.
```python
Text("Title", font_size=48, font="Inter", weight=BOLD) # body text
Text("code()", font_size=24, font="JetBrains Mono") # monospaced
MathTex(r"\nabla L") # math (uses LaTeX)
MONO = "Menlo" # define once at top of file
Text("Fourier Series", font_size=48, font=MONO, weight=BOLD) # titles
Text("n=1: sin(x)", font_size=20, font=MONO) # labels
MathTex(r"\nabla L") # math (uses LaTeX)
```
Minimum `font_size=18` for readability.
### Per-Scene Variation
Never use identical config for all scenes. For each scene:
@@ -141,11 +145,12 @@ BG = "#1C1C1C"
PRIMARY = "#58C4DD"
SECONDARY = "#83C167"
ACCENT = "#FFFF00"
MONO = "Menlo"
class Scene1_Introduction(Scene):
def construct(self):
self.camera.background_color = BG
title = Text("Why Does This Work?", font_size=48, color=PRIMARY)
title = Text("Why Does This Work?", font_size=48, color=PRIMARY, weight=BOLD, font=MONO)
self.add_subcaption("Why does this work?", duration=2)
self.play(Write(title), run_time=1.5)
self.wait(1.0)

View File

@@ -60,35 +60,40 @@ BG="#0A0A0A"; PRIMARY="#00F5FF"; SECONDARY="#FF00FF"; ACCENT="#39FF14"
## Font Selection
Manim's default `Text()` uses the system's default sans-serif font, which often renders with poor kerning. Always specify a font explicitly.
**Use monospace fonts for all text.** Manim's Pango text renderer produces broken kerning with proportional fonts (Helvetica, Inter, SF Pro, Arial) at all sizes and resolutions. Characters overlap and spacing is inconsistent. This is a fundamental Pango limitation, not a Manim bug.
Monospace fonts have fixed character widths — zero kerning issues by design.
### Recommended Fonts
| Use case | Font | Fallback |
|----------|------|----------|
| Body text, titles | `"Inter"`, `"SF Pro Display"` | `"Helvetica Neue"`, `"Arial"` |
| Code, terminal | `"JetBrains Mono"`, `"SF Mono"` | `"Menlo"`, `"Courier New"` |
| Math labels | Use `MathTex` (renders via LaTeX, not system fonts) | — |
| **All text (default)** | `"Menlo"` | `"Courier New"`, `"DejaVu Sans Mono"` |
| Code, labels | `"JetBrains Mono"`, `"SF Mono"` | `"Menlo"` |
| Math | Use `MathTex` (renders via LaTeX, not Pango) | — |
```python
# Clean body text
title = Text("Gradient Descent", font_size=48, font="Inter", weight=BOLD)
MONO = "Menlo" # define once at top of file
# Monospaced code
code_label = Text("loss.backward()", font_size=24, font="JetBrains Mono")
title = Text("Fourier Series", font_size=48, color=PRIMARY, weight=BOLD, font=MONO)
label = Text("n=1: (4/pi) sin(x)", font_size=20, color=BLUE, font=MONO)
note = Text("Convergence at discontinuities", font_size=18, color=DIM, font=MONO)
# Math — always use MathTex, not Text
equation = MathTex(r"\nabla L = \frac{\partial L}{\partial w}")
```
### When Proportional Fonts Are Acceptable
Large title text (font_size >= 48) with short strings (1-3 words) can use proportional fonts without visible kerning issues. For anything else — labels, descriptions, multi-word text, small sizes — use monospace.
### Font Availability
Not all fonts are installed on all systems. Manim falls back silently to a default if the font is missing. Use widely available fonts:
- **macOS**: SF Pro Display, SF Mono, Menlo, Helvetica Neue
- **Linux**: DejaVu Sans, Liberation Sans, Ubuntu, Noto Sans
- **Cross-platform**: Inter (install via Google Fonts), JetBrains Mono (install from jetbrains.com)
- **macOS**: Menlo (pre-installed), SF Mono
- **Linux**: DejaVu Sans Mono (pre-installed), Liberation Mono
- **Cross-platform**: JetBrains Mono (install from jetbrains.com)
For maximum portability, use `"Helvetica Neue"` (body) and `"Menlo"` (code) — both available on macOS and have Linux equivalents.
`"Menlo"` is the safest default — pre-installed on macOS, and Linux systems fall back to DejaVu Sans Mono.
### Fine-Grained Text Control
@@ -99,15 +104,15 @@ For maximum portability, use `"Helvetica Neue"` (body) and `"Menlo"` (code) —
MarkupText('<span letter_spacing="6000">HERMES</span>', font_size=18, font="Menlo")
# Bold specific words
MarkupText('This is <b>important</b>', font_size=24)
MarkupText('This is <b>important</b>', font_size=24, font="Menlo")
# Color specific words
MarkupText('Red <span foreground="#FF6B6B">warning</span>', font_size=24)
MarkupText('Red <span foreground="#FF6B6B">warning</span>', font_size=24, font="Menlo")
```
### Text Rendering Quality
### Minimum Font Size
Manim's text rendering quality depends heavily on output resolution. At `-ql` (480p), text kerning looks noticeably poor. Always preview text-heavy scenes at `-qm` (720p) or higher. See `references/rendering.md` for quality preset guidance.
`font_size=18` is the minimum for readable text at any resolution. Below 18, characters become blurry at `-ql` and barely readable even at `-qh`.
## Visual Hierarchy Checklist