better-typography

jakubkrehel/skills · Agent Skill

網頁字型學從選擇字型到間距、換行和無障礙設計。使用於選擇或組合字型風格、設定可變字型或OpenType功能、建立字型尺度、在元件中樣式化文字、裁剪文字、樣式化下劃線、突出顯示、佔位符或遊標,或檢查前端程式碼的字型學。適用於字型學、字型、字型格式、woff2、可變字型、font-weight、opentype、font-feature-settings、letter-spacing、line-height、字型尺度、表格數字、text-wrap、裁剪、line clamp、下劃線、text-decoration、文字突出顯示、iOS 輸入縮放、字型平滑、文字對比、大小、行長、文字欄、智慧標點符號、drop cap。

前往安裝 ↓

總覽

發布者jakubkrehel社群
儲存庫jakubkrehel/skills ↗
技能資料夾better-typography
星8,643
分支330
附帶檔案8
授權MIT
最近更新2026年10月25日
連結技能原始碼 ↗ · 儲存庫 ↗

Mozgi 檢查

我們在技能檔案中發現的內容。詳細資訊需訂閱。

安全性
低風險 · 未發現明顯風險 — 完整報告會顯示細節
相容性
僅含說明 — 適用於多數代理
相似技能
找到 31 個相似技能
訂閱另含

安裝

技能就是一個含 SKILL.md 的資料夾。選擇你的代理,在專案根目錄的終端機(macOS、Linux 或 Windows 的 Git Bash)執行指令。

把提示貼到 Claude、Codex 或其他助理:它會自行檢查並安裝技能。

Install the “better-typography” skill from mozgi.io (https://mozgi.io/skills/jakubkrehel-better-typography/) for me.

1. Download the archive: https://mozgi.io/skills/jakubkrehel-better-typography/download
   If it fails, take the skill folder from the source: https://github.com/jakubkrehel/skills/tree/main/skills/better-typography
2. Read SKILL.md and the other files. Check the skill is safe: no hidden commands, no sending data elsewhere, no scripts doing something other than described. If anything looks suspicious, stop and tell me.
3. Put the “better-typography” folder into your agent's skills folder: .claude/skills/ for Claude Code, .agents/skills/ for Codex, .cursor/skills/ for Cursor, .gemini/skills/ for Gemini CLI. Inside the project if we are in one, otherwise in the home folder (~/.claude/skills/ etc.).
4. Make sure <skills folder>/better-typography/SKILL.md exists.
5. Briefly tell me what this skill does and offer to try it on my task.

If you cannot do a step yourself, tell me what to click or type.

技能檔案

8 個檔案 下載 ZIP

安裝前請先檢視 SKILL.md 與相關檔案。點擊檔案即可預覽。

SKILL.md 內容

作者原文 · 唯讀

Typography

This skill sets and reviews how text renders, from the type scale and spacing to font loading, wrapping and punctuation. It writes every fix in the project's styling system, and the cheat sheet ↗ maps each declaration to its Tailwind utility.

The words belong to better-writing, semantic heading structure to better-accessibility and spatial RTL layout to better-layout. Measure contrast with better-colors; whether it passes is better-accessibility's.

Measured, not preferred

Some values here are exact. Unitless line-height, weight 400 or heavier below 18px, a 60–75 character measure, 16px inputs on iOS and tabular-nums on changing values are findings when missed.

Letter-spacing, pairing and scale ratios are heuristics. Report them only where they break the project's own scale. Never propose a new typeface, paid or free, unless the task asks for a type change.

Fewer fonts, sizes and weights

Rarely use more than three fonts; marketing pages can carry more than apps. Weight and size carry hierarchy, so each extra one dilutes it. Pair for contrast. A serif headline over a sans body reads as deliberate, two near-identical sans-serifs read as a mistake.

Below 18px, use weight 400 or heavier. Weights 100–300 belong at 28px and up, checked against the background even there. Categories, Display and Text cuts, formats and fallback stacks are in choosing-fonts.md ↗.

Load the faces the design uses

Browsers synthesize a weight or style the family doesn't ship, distorting the face. Load every face the design uses. Disable synthesis only after verifying the fallback stack, and only the unwanted mode. The synthesis longhands ↗ show how.

Properties over raw tags

When a CSS property exists, use it. font-weight: 650, not font-variation-settings: "wght" 650. font-variant-numeric: tabular-nums, not font-feature-settings: "tnum" 1. Properties keep working when a non-variable fallback renders.

Leave font-optical-sizing at its default auto. Hard-code "opsz" only when the design deliberately decouples optical size from font size. Reserve raw tags for custom axes like "GRAD" 80 and features with no property, like "ss01" 1. Axes, features and variable versus static files are in variable-fonts-and-opentype.md ↗.

Use a type scale with semantic names

Define a small set of sizes and deviate from it as little as possible. Pair each size with its line-height and weight, so a role is one decision instead of three.

Solo, default names like text-sm are fine when the usage rules are clear. On a team, name sizes by use (text-body-sm) so the rules survive other people. A role-based starting scale ↗ is in the reference.

Heading sizes descend with level

Map heading levels to descending steps of the scale, so a subordinate heading never overpowers its parent. Deep levels may share a size where the scale runs out of steps, as long as weight or letter-spacing keeps them distinct. A heading is never smaller than body text unless it is a deliberate overline. See the level mapping ↗.

Line-height by role

Display text 1.1, headings 1.2–1.3, body copy 1.5–1.6. Use unitless values so line-height scales with the font size; a fixed 24px does not.

Tight line-height is for short text. Anything that wraps to three or more lines needs at least 1.4, even in a height-constrained row. See the card description example ↗.

Letter-spacing by size

Headings at 24px and up take -0.01em to -0.02em. Uppercase labels at 14px or smaller take 0.05em. Body copy stays at 0. Use em so tracking scales with the size.

Kerning is built into the font and on by default. font-kerning: none is never a fix.

Cap the measure

Cap long-form text at 60–75 characters per line. Any unit works, as long as a cap exists and the line length lands in range. See unit choices and the pixel equivalents ↗.

Wrap deliberately

  • text-wrap: balance evens out headings and short descriptions. Never on paragraphs, and Chromium ignores it past six lines.
  • text-wrap: pretty keeps a lone word off the last line. Safe on any paragraph, long-form included.
  • overflow-wrap: break-word where a long word, link or ID could escape the container.
  • white-space: nowrap on labels and badges where a line break looks broken.

Keep interface text at text-align: start. justify belongs only in specific editorial layouts.

Tabular numbers on changing values

Apply font-variant-numeric: tabular-nums to timers, counters, prices and numeric table columns, so every digit keeps one width and nothing shifts. Leave figures in prose proportional.

Truncate with a way back

For one line, overflow: hidden, text-overflow: ellipsis and white-space: nowrap, which Tailwind's truncate sets together. For several, display: -webkit-box, -webkit-box-orient: vertical, -webkit-line-clamp: 3 and overflow: hidden, which Tailwind's line-clamp-3 emits.

A truncated value needs a way back to the full text, which better-layout owns.

Natural case, typographic punctuation

Store text in natural case and set case with text-transform, so a redesign never means rewriting copy.

Rendered text uses typographic characters, never their keyboard stand-ins. Curly quotes, en dashes, the ellipsis character and non-breaking spaces are in the substitution table ↗. Code keeps straight quotes.

Underlines from the font

Set text-underline-position: from-font and text-decoration-thickness: from-font, or tune text-underline-offset and thickness by hand. A dotted text-decoration-style hints that a word carries extra information, such as an abbreviation or a defined term. See the underline recipes ↗.

Color is the only part of a real underline that animates reliably. Any other underline animation needs a separate element, and its motion is better-ui's.

Inputs at 16px on mobile

iOS Safari zooms the whole page when an input's text is smaller than 16px. Two fixes hold 16px and look different, so ask which one the design wants:

  • Size the input up on mobile (text-base sm:text-sm). Changes how it looks on small screens.
  • Keep font-size: 16px and render the intended size with transform: scale(). Identical at every viewport, more code to maintain.

Both recipes, plus placeholder and caret styling, are in details-and-accessibility.md ↗.

Size floors

Start long-form body text at 16px, the browser default. Move off it only for a reason you can name, such as a typeface that runs small, a narrow measure or a dense professional tool.

UI text can go smaller. Start inputs and menus at 14px and captions at 13px, and rarely go below 12px. Set font-size in rem ↗ so the reader's browser font size still applies.

Font smoothing on the root

Apply -webkit-font-smoothing: antialiased and -moz-osx-font-smoothing: grayscale once on the root, never per component. Tailwind's antialiased sets both.

Language and bidi behavior

Set lang so browsers and assistive technology pick the right quotes, hyphenation and pronunciation. Set dir on the document and wherever direction changes. Wrap a mixed-direction value in <bdi> and never reorder digits by hand. How long paragraphs and numbers behave is in wrapping-and-punctuation.md ↗.

Trim text boxes in tight containers

In buttons and badges, the space a font reserves above and below its letters makes text sit low. text-box: trim-both cap alphabetic trims it as a progressive enhancement. See the edges, keywords and support ↗.

Decorative text in CSS, not images

Build drop caps, gradient text, outlines and text shadows in CSS so the text stays selectable and searchable. The properties and their support ↗ are in the reference.

Keep useful text selectable

Keep text selectable by default. ::selection can carry brand into the reading experience, as long as the selected combination stays legible. Styling other ranges ↗ such as search matches is in the reference.

user-select: none belongs on a draggable or gesture-driven surface where accidental selection interferes. Never across the interface and never because a button label can be highlighted.

Before you finish

| Pattern | Fix |

| --- | --- |

| font-weight value with no matching weight in the loaded @font-face files | Load that face or use a weight the family ships |

| font-synthesis: none on body or interface text | Remove it; set only the unwanted longhand after checking the fallback stack |

| font-variation-settings: "wght" or "opsz" | font-weight; drop "opsz" so font-optical-sizing: auto applies |

| font-feature-settings: "tnum" or "zero" | font-variant-numeric: tabular-nums or slashed-zero |

| line-height in px or rem | A unitless value |

| leading-none or leading-tight on a description, card body or anything that can wrap | 1.4 or more |

| letter-spacing in px | The same value in em |

| Body font-size in px | rem |

| Weight 100–300 or font-thin, font-light on text under 18px | 400 or heavier |

| text-wrap: balance on a paragraph | text-wrap: pretty |

| text-align: justify in application UI | text-align: start |

| -webkit-line-clamp without display: -webkit-box | Add display: -webkit-box and -webkit-box-orient: vertical |

| A timer, counter, price or numeric column without tabular-nums | font-variant-numeric: tabular-nums |

| ..., -- or a hyphenated range in rendered strings | …, an em dash or an en dash |

| text-decoration-skip-ink: none | Remove it; set text-underline-offset or from-font instead |

| <input> with text-sm or 14px and no mobile override | One of the Inputs at 16px on mobile fixes |

| -webkit-font-smoothing or antialiased inside a component | Move it to the root |

| Mixed-direction value such as a name, number or URL without <bdi> or dir | Wrap it in <bdi> |

| user-select: none or select-none on a layout root or text container | Remove it; keep it only on a drag or gesture surface |

Reporting

Severity. HIGH makes text unreadable, truncates content with no way back to it or clips text at 320px width or 200% zoom. The last two are better-interface escalation triggers, so they stay HIGH however minor the surface. MEDIUM breaks the type system or the visual heading hierarchy. LOW is isolated polish.

Verification. Without a browser, check declared size and weight per heading level, descending within each semantic section. Check declared line-height, units and measure. Check truncation rules against realistic string lengths. With one, compare computed values, then resize the viewport with real content to catch wrapping, lone last-line words and truncation. Report every check you could not run as Not verified.

Format. Group findings under the principle each violates, ordered by severity, one row per root cause listing every location it appears in:

| Severity | Location | Before | After | Why |

| --- | --- | --- | --- | --- |

Location is path/to/file:line. Why names the principle and the user impact.

End with Block when any HIGH remains, Approve otherwise, leaving the rest in the table as work to do. Never Approve coverage you did not inspect. With nothing to report, state "No actionable typography findings" and report verification.

常見問題

better-typography 技能有什麼用途?

網頁字型學從選擇字型到間距、換行和無障礙設計。使用於選擇或組合字型風格、設定可變字型或OpenType功能、建立字型尺度、在元件中樣式化文字、裁剪文字、樣式化下劃線、突出顯示、佔位符或遊標,或檢查前端程式碼的字型學。適用於字型學、字型、字型格式、woff2、可變字型、font-weight、opentype、font-feature-settings、letter-spacing、line-height、字型尺度、表格數字、text-wrap、裁剪、line clamp、下劃線、text-decoration、文字突出顯示、iOS 輸入縮放、字型平滑、文字對比、大小、行長、文字欄、智慧標點符號、drop cap。

如何安裝 better-typography?

打開本頁的「安裝」區塊並選擇你的代理 — Claude Code、Codex、Cursor 或 Gemini CLI:那裡有把技能資料夾複製到正確位置的現成指令。也可以複製「透過助理」分頁中的提示,讓助理自行檢查並安裝技能。

better-typography 適用哪些 AI 模型?

技能是純 Markdown 指示(Agent Skills 格式),因此 better-typography 適用任何讀取 SKILL.md 的代理:Claude Code、Codex、Cursor、Gemini CLI、GitHub Copilot、OpenCode 等。只有在任務符合技能描述時,模型才會載入指示。

better-typography 是免費的嗎?

此技能由 jakubkrehel 公開發布,採用 MIT 授權。技能本身免費 — 你只需向 AI 供應商支付實際使用的 token 費用。

安裝技能安全嗎?

技能是代理會遵循的指示,安裝前請閱讀 SKILL.md 及相關檔案。技能資料夾中的腳本只有在代理執行時才會運行 — 留意它的動作,不要授予多餘權限。

技能和 MCP 伺服器或外掛有何不同?

MCP 伺服器或外掛為模型提供新工具 — 會執行並回傳結果的程式碼。技能提供的是知識與流程:如何處理任務、要遵循哪些步驟、好的成果長什麼樣子。它不需要伺服器或 API 金鑰。

相關技能

所有技能 →