UI typography on Apple platforms — text styles and Dynamic Type, the San Francisco family (Pro/Rounded/Compact/Mono/New York + width axis), optical sizes, tracking vs kerning, leading adjustments, and custom-font scaling. Use when choosing fonts, building type hierarchy, fixing truncation/legibility, or making custom fonts respect Dynamic Type.
Type is most of your UI. The system does the hard parts — optical sizes, tracking tables, Dynamic Type — if you use its APIs. This skill covers when to trust the system, how to build hierarchy deliberately, and what custom fonts owe you back.
Predefined styles (Large Title → Caption 2) are weight + size + leading combos with Dynamic Type support built in — and different styles scale differently (body grows more than footnote), which manual font sizes can't replicate.
allowsTightening (default-tightening-for-truncation) instead of
manually squeezing — and prefer wrapping to truncating (line limit 0 on labels that matter).12 sizes: 7 default + 5 accessibility (AX1–AX5). .body runs 17pt at default up to 53pt
at AX5 — roughly 3× taller, and layouts must expect that. Escalate in order:
.font(.title) / preferredFont(forTextStyle:) +
adjusts-for-content-size, line count 0 so text wraps instead of truncating.@ScaledMetric for the non-text riding alongside (icon frames, spacing); SF
Symbols scale via UIImage.SymbolConfiguration(textStyle:). Prioritize scaling
essential content over decoration.dynamicTypeSize.isAccessibilitySize with AnyLayout(HStackLayout()) /
AnyLayout(VStackLayout()) (UIKit: flip the stack axis on
preferredContentSizeCategory.isAccessibilityCategory); give text the full line
width and relax lineLimit.Test at all 12 sizes (Xcode Previews → Variants → Dynamic Type Variants), not just the biggest — mid-range accessibility sizes catch different wrap points.
| Face | Job |
|---|---|
| SF Pro | The default; UI text everywhere |
| SF Pro Rounded | Friendlier numerals/labels — widgets, health/fitness data |
| SF Compact | watchOS (space-efficient counterpart) |
| SF Mono | Code, tabular alignment |
| New York | Serif — reading experiences, editorial contrast |
| SF Arabic / SF Arabic Rounded | Arabic script with its own optical sizes |
The width axis (Condensed / Regular / Compressed / Expanded):
System fonts get Dynamic Type free; a brand font makes you the type engine:
UIFontMetrics(forTextStyle:).scaledFont(for:) + adjusts-for-content-size, or
SwiftUI Font.custom(_:size:relativeTo:); scale layout constants with @ScaledMetric.system-ui, ui-rounded, ui-serif, ui-monospace
on the web).❌ Anti-patterns: hardcoded point sizes on user-facing text · kerning APIs for tracking jobs ·
custom font without relativeTo: (frozen size) · Compressed body text · truncation where
wrapping was possible.
Type review: Element | Current (font/size/style) | Issue (hierarchy/scaling/legibility) | Fix
— check Dynamic Type at XXL + AX sizes before signing off; pairs with the contrast rules in
generators/accessibility-generator.
design/sf-symbols (symbols align to text styles), foundation/attributed-string (rich text mechanics), generators/accessibility-generatorfreekmurze/dotfiles
fe89482
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.