Microtypography
Typography skills for AI coding agents — 20 focused skills + a /type router, extracted from 10 canonical typography books and reconciled against WCAG 2.2 and current browser behavior.
npx -y skills add jpoindexter/typography-skills --skill microtypographyAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 10 days oldThe repository was created 10 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when text is technically correct but reads poorly — uneven word spacing, rivers, bad rags, orphans and widows, awkward hyphenation, loose or tight tracking, wrong quote marks and dashes, cramped all-caps. Also use when a design "feels cheap", "looks AI-generated", or "something is off" and the cause is spacing detail rather than font choice.
SKILL.md
15.9 KB, as published. Nobody here has run it
Microtypography
The layer below font choice. When a page feels amateur despite a good typeface, the defect is almost always here. Hochuli's subject: "all the small things that enhance the legibility of texts."
1. When to invoke
- Text is set correctly by every macro rule and still reads badly.
- Uneven word spacing, visible rivers, ragged edges that clump.
- Orphans, widows, a heading stranded at a column foot.
- Wrong apostrophes, hyphens standing in for dashes, cramped capitals.
- Someone says the work looks "generic", "cheap", or "AI-generated."
Do not invoke to pick a typeface (typeface-selection) or set a scale
(hierarchy-and-scale).
2. Required context
- The rendered text — microtypography cannot be judged from source.
- Whether setting is justified or ragged, and the measure in characters.
- Whether the text is user-generated (you cannot hand-fix it — the rules must be systemic).
- Language and script — spacing conventions are not universal.
- Whether the typeface carries the needed OpenType features (real small caps, oldstyle figures, proper kerning pairs).
3. Invariant principles
- Word spaces should be even and unobtrusive. They separate words; they should not be seen as shapes in their own right.
- Rivers are defects. When word spaces in successive lines fall under one another they form vertical channels that "disturb the flow of the text"; the make-up should be adjusted to remove them. (Hochuli)
- Justification below ~50 characters per line fails. Even word spacing becomes "difficult, if not impossible" and large holes appear. Below that measure, set ragged. (Hochuli)
- Ragged setting is a legitimate aesthetic choice at any measure, not merely a fallback: even word spacing makes the text regular, while the irregular right margin makes it lively. (Hochuli)
- A paragraph needs exactly one unambiguous separation signal — indent or space, never both.
- Punctuation has correct forms.
'and"are typewriter marks, not quotes. Hyphen, en dash, and em dash are three different characters with three different jobs. - Turn standard ligatures off wherever you letterspace — a tracked
filigature reads as broken. See../type/references/opentype-features.md. - Capitals and small caps always need letterspacing. Set solid, they read as a cramped block. Lowercase set for text does not.
4. Context-dependent heuristics
Paragraph separation — a real print/web conflict. Hochuli, citing Tschichold, holds that indents are "the only certain indicators of a new paragraph," and that using blank lines "breaks up the page, requires too much space, and creates problems when a paragraph ends at the bottom of a page."
That reasoning is about bound pages. On the web there is no page bottom, and
WCAG 1.4.12 requires paragraph spacing to survive a 2em user override. So:
- Continuous prose in a paged/print or ebook context → indent, no blank line.
- Web, docs, UI, anything scrolled → space between paragraphs, no indent.
- Never both. Never a first-paragraph indent directly under a heading.
Source hierarchy: rule 1 and rule 2 outrank rule 6 here.
Kerning is not tracking, and people almost always mean tracking. Stocks: "Everyone likes to point out bad kerning… most of the time they mean tracking."
- Kerning — the space between two specific glyphs (the
AVpair,To). Handled by the font's kern table; you adjust it only for display-size type where one pair is visibly wrong. Never kern body text by hand. - Tracking — the overall letter spacing across a block of text. This is the
control you actually reach for. In CSS it's
letter-spacing.
If someone reports "bad kerning" in running text, they are describing tracking, a poorly-spaced font, or a rag problem. Diagnose before adjusting.
Tracking.
| Case | Guidance |
|---|---|
| Body text at reading size | Leave at the designer's default — 0 |
| Display sizes (large headings) | Tighten slightly; type spaced for text is loose when scaled up |
| All-caps and small caps | Add positive tracking, always |
| Small sizes / low contrast / dark-on-light inversion | Slightly positive |
| Any text a user can override | Must survive letter-spacing: .12em (WCAG 1.4.12) |
Two hard rules on tracking:
- Never set letter spacing in absolute units. Tracking, like line-height, must
be relative to the type itself (
em) so it scales with the size.letter-spacing: 1pxis wrong at every size except the one it was tuned for. - Negative tracking works only at large sizes, and then only slightly. Below display size it degrades legibility, and it collides with the 1.4.12 override.
Typographic colour. The density of a block of text — its overall grey value, nothing to do with hue. Stocks: it "refers to the text density on a page… consider it a squint test." Crucially, colour is set not just by line-height and tracking but by "all those in-between spaces, too, like counters, serifs, and the very shapes of the letters."
This is the diagnostic behind most "something feels off" reports. Squint at the block: if some areas go darker or lighter than others, you have uneven colour — caused by rivers, inconsistent word spacing, a weight that's too light for the size, or a heading whose stroke thickness doesn't match the body's apparent weight. Even colour is what makes a page look professionally set.
Alternative spaces. A regular word space around an em or en dash is often too open. Hair spaces and thin spaces exist for this, and for separating a dash from adjacent characters without opening a hole. House style decides between a closed-up em dash, a spaced en dash, and a hair-spaced em dash — but pick one and apply it consistently, because mixing them is visible.
Hyphenation and rag. Hyphenation lets justified text hold even word spacing; without it, narrow justified columns are unsalvageable. For ragged setting, judge the rag itself: it should look accidental, not form shapes, stair-steps, or a near-justified edge that reads as a mistake. Avoid more than two consecutive hyphenated lines.
Orphans and widows. A single word alone on the last line of a paragraph, or a
single line stranded at the top or bottom of a column. In CSS, orphans/widows
handle column breaks; text-wrap: pretty addresses the last-line orphan and
text-wrap: balance evens short blocks like headings. Both are progressive
enhancements — unsupported browsers fall back to normal wrapping with no breakage.
Hanging punctuation (optical margin alignment). A quotation mark or hyphen at the start of a line optically breaks the column's left edge. Lupton: hanging punctuation "prevents quotation marks from taking a bite out of the crisp left edge of a text block" — you "create a sharp edge by pushing the quotation marks into the margin."
CSS hanging-punctuation: first last; does this natively but is Safari-only at time
of writing, so treat it as progressive enhancement. For a pull quote or blockquote
where the effect matters, a negative text-indent on the first line is the reliable
fallback. Don't hand-hang punctuation in body copy — it won't survive reflow.
Controlling breaks without polluting content.
| Need | Use |
|---|---|
| Keep two words together ("12 kg", "Mr Smith") | — non-breaking space |
| Offer a break point inside a long word | ­ — soft/discretionary hyphen; shows only if the break is used |
| Offer a break with no hyphen (long URLs) | <wbr> |
| Prevent a break in a phrase | white-space: nowrap on a span |
Rutter distinguishes the ordinary hyphen (always displayed — fly-by-wire, or
disambiguating twenty-four hour shifts) from the soft hyphen, which appears only
when the line actually breaks there. And his blunt rule on the pairing: "to
justify text without hyphenating is to wilfully harm the reading experience."
Prefer automatic hyphens: auto with a correct lang attribute; reach for ­
only for words the dictionary gets wrong.
Accents and diacritics are not optional. Rutter: "if a word has an accent, use
it," and "pay particular attention to accented names." Dropping the accent in a
personal name is a correctness error and often a discourtesy — Bronte is not
Brontë, Beyonce is not Beyoncé. Verify the shipping font actually carries the
marks (see typeface-selection) and that the marks aren't clipped by a tight
line-height (see international-typography).
Prefer UTF-8 characters to HTML entities. Serve the page as UTF-8 and type the
real character — —, …, é, ×. Entities (—, …) make source
unreadable, break search-and-replace, and are a legacy workaround. Automate the
substitution at the content pipeline rather than asking authors to remember.
A few characters people reliably get wrong:
- Use a real multiplication sign
×and division sign÷, notxand/. - Don't set brackets and parentheses in italic just because the enclosed text is italic — the upright forms belong to the sentence, not the phrase.
- Don't over-elaborate the ampersand. A decorative
&is a display device; in running text it's noise. - Delete stray spaces before punctuation and at line ends — they open holes and shift the rag.
Punctuation quick table.
| Use | Character |
|---|---|
| Word joining, line-break hyphenation | hyphen - |
| Ranges, "1998–2004" | en dash – |
| Parenthetical break | em dash — (or spaced en dash, house style) |
| Apostrophe, single quote | ' ' |
| Double quote | " " |
| Ellipsis | … not ... |
| Minus sign | − not hyphen |
5. Failure patterns
| Pattern | Cause | Fix |
|---|---|---|
| "Holes" in justified text | Measure too narrow, hyphenation off | Enable hyphenation, widen measure, or set ragged |
| Vertical rivers | Coincident word spaces across lines | Adjust make-up, re-break, or set ragged |
| Both indent and blank line between paragraphs | Two separation signals | Pick one |
| Cramped all-caps heading | No tracking added | Add positive tracking |
| Straight quotes in production copy | No smart-quote transform | Fix at the content pipeline, not by hand |
| Heading tightened globally and body went tight too | Tracking applied to a shared token | Scope tracking to display sizes |
| A single word on a heading's second line | No text-wrap: balance | Add it (progressive enhancement) |
| Small caps look like shrunken capitals | Faux small caps | Use a font with real smcp |
| "The kerning is bad" in a paragraph | Tracking, font spacing, or rag — not kerning | Diagnose before adjusting; kerning is per-pair |
| Tracking correct at one size, wrong at others | letter-spacing in px | Use em |
| Block looks patchy/mottled when squinted | Uneven typographic colour | Find the cause: rivers, word spacing, weight mismatch |
| Heading looks weaker than the body it sits above | Stroke thickness lighter than body's apparent weight | Match apparent weight, not nominal |
| Dashes sit in visible holes | Full word spaces around an em dash | Hair/thin space, or close it up — consistently |
6. Evaluation procedure
- Render at real size, then squint. This is the typographic-colour test and it comes first: rivers, uneven word spacing, and weight mismatches appear as blotchy texture before they resolve into detail. An evenly grey block passes.
- Scan word spacing down the block. Even? Any vertical channels?
- If justified: count CPL. Under ~50 → change to ragged or widen.
- If ragged: is the edge accidental, or does it form a shape or stair-step?
- Check every paragraph boundary for exactly one separation signal.
- Check the last line of each paragraph for orphans; check column tops/bottoms for widows.
- Grep the copy for
',",-,...— replace with correct characters. - Check all-caps and small-cap runs for tracking.
- Apply WCAG 1.4.12 overrides (
letter-spacing: .12em,word-spacing: .16em) and confirm nothing breaks.
7. Output format
Defects found (ranked by reading impact):
1. <defect> — <where> — cause: <cause> — fix: <fix>
...
Setting: <justified|ragged> at <N> CPL — <appropriate|not>
Paragraph signal: <indent|space> — <single|doubled ✗>
Punctuation: <n> straight quotes, <n> hyphen-as-dash, <n> ...
1.4.12 override: <pass|fail>
Unverified: <what was not checked in a rendered context>
8. Examples
A marketing page that "looks cheap" despite a good typeface.
The typeface is fine. Three microtypographic defects are doing the damage: the hero heading is set in all-caps at default tracking, so it reads as a cramped block; body paragraphs carry both a first-line indent and a blank line, giving two separation signals; and the copy uses straight quotes throughout. Fix the tracking on the caps token, drop the indent, and add a smart-quote transform at the content layer — the font choice needs no change.
A 38-CPL justified sidebar with visible holes.
Justification is failing because the measure is far below the ~50 CPL floor where even word spacing is achievable. Widening isn't available in this layout, so set the sidebar ragged. Word spaces become even; the ragged right edge is the correct trade and reads as deliberate.
9. Counterexamples
- ❌ "Add
letter-spacing: -0.02emto body text to tighten it up." — Text-size type is already spaced correctly by its designer. Tightening body text harms legibility and may collide with the WCAG 1.4.12 override. - ❌ "Justify the text so it looks clean and formal." — At a narrow measure, justification produces holes and rivers, which is the opposite of clean.
- ❌ "Use
before the last word to fix the orphan." — Brittle, breaks at other viewports, and pollutes content. Usetext-wrap: pretty. - ❌ "Indent the first line of every paragraph, including the one after the heading." — The heading already signals the paragraph start; the indent is redundant there.
- ❌ "Small caps via
font-variant: small-capsalways looks right." — Without a realsmcpset the browser may synthesize them by scaling capitals, which produces visibly too-light strokes.
10. Source citations
- Hochuli, Detail in Typography — primary source. Rivers and page make-up; the ~50 CPL floor for justified setting; ragged setting as an aesthetic choice; Tschichold on indents as the only certain paragraph indicator; fixation behavior around capitals and long words.
- Lupton, Thinking with Type 3e — typographic conventions, punctuation forms.
- Stocks, Universal Principles of Typography — §22 "a little tracking goes a long
way"; §53 "typographic color is about density" — the squint test, and colour being
dictated by counters, serifs, and letterform shapes as well as spacing; §56–57
dashes and alternative spaces; §58 italicize punctuation and spaces too; §60
widows and orphans; §61 optical trickery; §76 "kern only if you have to" — the
kerning/tracking confusion, kerning being the space between two specific glyphs;
and the rule that letter spacing must never use absolute units. Full index in
../type/references/universal-principles-index.md. - Rutter, Web Typography — hyphenation and justification on the web.
- WCAG 2.2 §1.4.12 (text spacing override).
- MDN —
text-wrap:balanceis supported in Chrome/Edge 114+, Firefox 121+, Safari 17.5+;prettyin Chrome/Edge 117+ and Safari 26+, not yet Firefox. Chromium appliesbalanceonly to blocks of ≤6 lines. Both degrade silently.