☰
Dillinger 移动端排版实战指南:系统字体、Dynamic Type 与无障碍可读性
2026/9/26 8:07:54 网站建设 项目流程
  • 前端
  • 开发工具

【免费下载链接】dillinger

The last Markdown editor, ever.

项目地址:https://gitcode.com/gh_mirrors/di/dillinger
点击查看免费下载

本篇技术指南以开源仓库中的移动端排版参考文档 .agent/skills/mobile-design/mobile-typography.md 为骨架,系统讲解移动端字体的设计基础、iOS/Android 系统字体体系、类型尺度、Dynamic Type 文本缩放、WCAG 无障碍要求、暗色模式排版以及字体加载性能优化。文中将结合 Dillinger 仓库实际的排版实现(tailwind.config.ts、app/globals.css)与自动化审计脚本 mobile_audit.py 进行纵深佐证。读完你能够:为 iOS/Android(React Native、Flutter 或原生)应用建立可缩放、可访问的排版体系,并具备对现有实现做排版审计的能力。

文档开宗明义地指出一个核心论断:排版失败是移动应用不可读的第一大原因(Typography failures are the #1 cause of unreadable mobile apps)。移动端排版不是装饰,而是用户与内容之间的主界面。


1. 移动端排版基础:为什么移动端与桌面端截然不同

1.1 移动端字体的差异根源

移动设备与桌面显示器的物理与交互环境存在本质差异,这是移动端排版设计的第一性原理。文档给出了如下对比:

DESKTOP: MOBILE: ├── 20-30" viewing distance ├── 12-15" viewing distance ├── Large viewport ├── Small viewport, narrow ├── Hover for details ├── Tap/scroll for details ├── Controlled lighting ├── Variable (outdoor, etc.) ├── Fixed font size ├── User-controlled sizing └── Long reading sessions └── Quick scanning

四条关键差异直接决定了设计决策:

  1. 观看距离更近(12–15 英寸):同样的字号在近距观看下"看起来更大",但同时也意味着用户对字体的清晰度更敏感,抗锯齿与字重渲染质量要求更高;
  2. 视口更小更窄:每行能容纳的字符数急剧下降,正文行宽必须控制在 40–60 字符,否则换行过于频繁、阅读追踪困难;
  3. 环境光照不可控:用户可能在户外强光下使用,低对比度文本会"隐形",因此对比度要求比桌面更严格(AA 为底线,AAA 更优);
  4. 字号由用户控制:iOS 的 Dynamic Type 与 Android 的字体缩放(85%–200%)意味着开发者无法假定某个固定 px 值在用户设备上成立,排版必须"可缩放"。

1.2 移动端排版规则速查表

规则桌面端移动端
最小正文字号14px16px(14pt/14sp)
最大行长75 字符40–60 字符
行高1.4–1.51.4–1.6(更宽松)
字重多样Regular 为主,粗体克制使用
对比度AA(4.5:1)AA 为最低要求,AAA 优先

移动端的核心心法是"Regular 字重主导 + 粗体克制"。从 Dillinger 的预览排版实现 app/globals.css 可以看到同样的思路:正文font-size: 14px; line-height: 1.7,标题统一使用font-weight: 600(Semibold 而非更重的 Bold),通过字号与行距而非字重爆炸来建立层级。


2. 系统字体:iOS 与 Android 的字体体系

2.1 iOS:SF Pro 家族

iOS 的系统字体是 San Francisco(SF)家族,按用途分为五个子族:

San Francisco (SF) Family: ├── SF Pro Display: 大号文本(≥ 20pt) ├── SF Pro Text: 正文文本(< 20pt) ├── SF Pro Rounded: 友好/趣味场景 ├── SF Mono: 等宽字体 └── SF Compact: Apple Watch、紧凑界面

SF Pro 的核心特性:

  • 光学尺寸(Optical sizing):字体根据实际渲染字号自动切换 Display/Text 形态,保证大标题与正文各自的最优字面比例;
  • 动态字距(Dynamic tracking):字母间距随字号动态调整,大字号自动收紧、小字号自动放宽,弥补大字号视觉上"字距偏松"的错觉;
  • 表格/比例数字(Tabular/proportional figures):适合数据表格与正文两种场景;
  • 出色的易读性(Excellent legibility):专为屏幕渲染优化。

2.2 Android:Roboto 家族

Android 的系统字体是 Roboto,同样是一个完整家族:

Roboto Family: ├── Roboto: 默认无衬线字体 ├── Roboto Flex: 可变字体(variable font) ├── Roboto Serif: 衬线选项 ├── Roboto Mono: 等宽 ├── Roboto Condensed: 窄空间

Roboto 的特性:

  • 针对屏幕优化(Optimized for screens):在低分辨率与 OLED 屏幕上都有良好表现;
  • 广泛的语言支持(Wide language support):适合全球化应用;
  • 多字重(Multiple weights):覆盖 100–900 全部字重;
  • 小字号表现佳(Good at small sizes):小字号下笔画依然清晰可辨。

2.3 何时使用系统字体:决策清单

✅ 应该使用系统字体的场景:

├── 品牌没有强制要求自定义字体 ├── 阅读效率是首要目标 ├── 应用需要"原生/融为一体"的感觉 ├── 性能是关键约束(零下载成本) ├── 需要广泛的语言支持

❌ 应避免系统字体的场景:

├── 品牌形象要求自定义字体 ├── 需要通过字体实现设计差异化 ├── 编辑/杂志风格(editorial/magazine style) └── (即便如此,也必须支持无障碍缩放)

2.4 自定义字体的考量清单

如果决定使用自定义字体,必须逐项确认:

If using custom fonts: ├── 包含所有需要的字重(Include all weights needed) ├── 子集化以控制文件体积(Subset for file size) ├── 在所有 Dynamic Type 字号下测试(Test at all Dynamic Type sizes) ├── 提供系统字体回退(Provide fallback to system) ├── 测试渲染质量(Test rendering quality) └── 检查语言支持(Check language support)

仓库佐证:系统字体回退栈的工程化落地在 Dillinger 的 tailwind.config.ts 中,字体族被定义为多层回退栈,这正是"自定义字体 + 系统字体兜底"原则的 Web 端实现:

fontFamily: { sans: ['"Source Sans Pro"', '"Helvetica Neue"', "Helvetica", "Arial", "sans-serif"], serif: ["Georgia", "Cambria", "serif"], mono: ['"Ubuntu Mono"', "Monaco", "monospace"], },

每个字体族的第一项是品牌自定义字体(Source Sans Pro / Georgia / Ubuntu Mono),随后紧跟平台原生字体(Helvetica Neue / Monaco)与通用字体族兜底。当自定义字体加载失败或缺失某字符时,浏览器会平滑降级到系统字体,用户依然能获得可读的排版——这与移动端"自定义字体必须提供系统回退"的要求完全同构。


3. 类型尺度:iOS、Material 3 与自定义模块化比例

3.1 iOS 内建类型尺度(Dynamic Type 文本样式)

iOS 提供 11 级内建文本样式,随用户系统设置自动缩放:

样式字号字重行高
Large Title34ptBold41pt
Title 128ptBold34pt
Title 222ptBold28pt
Title 320ptSemibold25pt
Headline17ptSemibold22pt
Body17ptRegular22pt
Callout16ptRegular21pt
Subhead15ptRegular20pt
Footnote13ptRegular18pt
Caption 112ptRegular16pt
Caption 211ptRegular13pt

注意观察两个细节:行高始终约为字号的 1.2–1.3 倍(如 Body 17pt/22pt ≈ 1.29),这与第 5 节无障碍行高的推荐一致;同时标题字号从 34pt 到 17pt 逐级递减,形成清晰的层级梯度。

3.2 Android 类型尺度(Material 3)

Material Design 3 定义了 15 个文本角色(Text Role),以 sp 为单位:

角色字号字重行高
Display Large57sp40064sp
Display Medium45sp40052sp
Display Small36sp40044sp
Headline Large32sp40040sp
Headline Medium28sp40036sp
Headline Small24sp40032sp
Title Large22sp40028sp
Title Medium16sp50024sp
Title Small14sp50020sp
Body Large16sp40024sp
Body Medium14sp40020sp
Body Small12sp40016sp
Label Large14sp50020sp
Label Medium12sp50016sp
Label Small11sp50016sp

规律:Display/Headline/Title/Body 四档以 400 常规字重为主,Label 与 Title Medium/Small 使用 500 中字重以承担按钮、标签等功能性文本。

3.3 自定义类型尺度:模块化比例(Modular Ratio)

iOS 与 Android 的内建尺度覆盖了绝大多数场景,但当品牌需要自定义尺度时,应使用数学化的模块化比例生成字号,而不是随手挑数值。推荐比例:

Recommended ratios: ├── 1.125 (Major second 大二度): 密集 UI ├── 1.200 (Minor third 小三度): 紧凑 ├── 1.250 (Major third 大三度): 均衡(常用) ├── 1.333 (Perfect fourth 纯四度): 宽敞 └── 1.500 (Perfect fifth 纯五度): 戏剧化

以 1.25 比例、16px 基准的完整示例:

├── xs: 10px (16 ÷ 1.25 ÷ 1.25) ├── sm: 13px (16 ÷ 1.25) ├── base: 16px ├── lg: 20px (16 × 1.25) ├── xl: 25px (16 × 1.25 × 1.25) ├── 2xl: 31px ├── 3xl: 39px └── 4xl: 49px

仓库佐证:模块化比例的姊妹文档仓库中另一份前端排版文档 .agent/skills/frontend-design/typography-system.md 系统阐述了同一原理:选定基准字号(正文通常 16–18px)与比例(移动应用常用 1.2 小三度、Web 常用 1.25 大三度),然后用base × ratio^n生成整条尺度。这也印证了审计脚本对"字号是否遵循模块化比例"的检查逻辑(见第 4 节 9.3 检查项)。


4. Dynamic Type 与文本缩放(MANDATORY 强制要求)

4.1 iOS Dynamic Type:必须使用语义化文本样式

iOS 的 Dynamic Type 允许用户全局调整系统字号,应用必须跟随这一设置。错误示范是写死固定字号:

// ❌ WRONG: Fixed size (doesn't scale) Text("Hello") .font(.system(size: 17)) // ✅ CORRECT: Dynamic Type Text("Hello") .font(.body) // Scales with user setting // 自定义字体也要声明相对尺度 Text("Hello") .font(.custom("MyFont", size: 17, relativeTo: .body))

即使使用自定义字体,也必须通过relativeTo:将其锚定到某个内建文本样式上,才能随 Dynamic Type 缩放。

4.2 Android 文本缩放:必须使用 sp 单位

Android 侧的唯一铁律是:文本一律使用 sp(Scale-independent Pixels)。

ALWAYS use sp for text: ├── sp = Scale-independent pixels(与缩放无关的像素) ├── 随用户字体偏好缩放 ├── dp 不缩放(不要用于文本)

用户可将系统字体从 85% 缩放到 200%:

├── 默认(100%): 14sp = 14dp ├── 最大(200%): 14sp = 28dp

必须在 200% 下测试布局!一个 14sp 的文本在最大缩放时会占用 28dp 的空间,固定高度的容器必然溢出。

4.3 文本缩放带来的布局挑战与对策

大字号下常见的问题:

Problems at large text sizes: ├── 文本溢出容器(Text overflows containers) ├── 按钮变得过高(Buttons become too tall) ├── 图标相对文本显得过小(Icons look small relative to text) ├── 布局崩溃(Layouts break) Solutions: ├── 使用弹性容器,不要固定高度(Use flexible containers) ├── 允许文本换行(Allow text wrapping) ├── 图标随文本缩放(Scale icons with text) ├── 开发期间就在极端尺寸下测试(Test at extremes) ├── 长文本使用可滚动容器(Use scrollable containers)

仓库佐证:审计脚本如何自动检查缩放支持移动端审计脚本 .agent/skills/mobile-design/scripts/mobile_audit.py 的 4.2 检查项专门扫描 React Native 代码:一旦检测到fontSize:存在但没有任何allowFontScaling: true/responsiveFontSize/useWindowDimensions缩放机制,就会给出警告:

[Typography] {filename}: Fixed font sizes without scaling support. Consider allowFontScaling for accessibility.

该脚本还检查行高上限(lineHeight超过 1.8 会被标记"对移动端过高")、字号下限(小于 12px 触发可读性警告)与上限(大于 32px 建议改用响应式缩放),详见 mobile_audit.py。这意味着"缩放支持"不仅是设计原则,还可以作为 CI 中可量化的审计项。


5. 排版无障碍:最小尺寸、对比度与行高

5.1 最小字号表

元素最小推荐
正文(Body text)14px/pt/sp16px/pt/sp
次要文本(Secondary text)12px/pt/sp13–14px/pt/sp
注释(Captions)11px/pt/sp12px/pt/sp
按钮(Buttons)14px/pt/sp14–16px/pt/sp
任何内容不得小于11px-

5.2 WCAG 对比度要求

普通文本(< 18pt 或 < 14pt 粗体): ├── AA: 对比度 ≥ 4.5:1(最低要求) ├── AAA: 对比度 ≥ 7:1(推荐) 大号文本(≥ 18pt 或 ≥ 14pt 粗体): ├── AA: 对比度 ≥ 3:1(最低要求) ├── AAA: 对比度 ≥ 4.5:1(推荐) Logo/装饰性元素: 无要求

5.3 无障碍行高(WCAG 1.4.12 成功准则)

WCAG 对文本间距有明确的量化要求:

Line height(行距): ≥ 1.5× 字号 Paragraph spacing(段距): ≥ 2× 字号 Letter spacing(字距): ≥ 0.12× 字号 Word spacing(词距): ≥ 0.16× 字号

移动端推荐值:

├── 正文: 行高 1.4–1.6 ├── 标题: 行高 1.2–1.3 ├── 任何文本不得低于 1.2

仓库佐证:Dillinger 预览排版的行高实践在 app/globals.css 中,Dillinger 的 Markdown 预览正文设置了line-height: 1.7,高于 WCAG 的 1.5 下限、落入移动端推荐区间(1.4–1.6 之上),适合长文阅读;标题则通过margin-top: 1.5em; margin-bottom: 0.5em保证段落间距达到 2× 字号的量级(对应 WCAG 段距要求)。这种"正文宽松、标题紧凑"的层次与移动端推荐完全一致。


6. 暗色模式排版

6.1 颜色调整原则

Light Mode: Dark Mode: ├── 黑色文本 (#000) ├── 白色/浅灰文本 (#E0E0E0) ├── 高对比度 ├── 略降低的对比度 ├── 全饱和度 ├── 去饱和的颜色 └── 深色 = 强调 └── 浅色 = 强调

铁律:暗色模式下不要使用纯白(#FFF)。应使用介于 #E0E0E0 到 #F0F0F0 之间的米白(off-white)来减轻眼部疲劳。

6.2 暗色模式层级色表

层级亮色模式暗色模式
主文本(Primary text)#000000#E8E8E8
次文本(Secondary text)#666666#A0A0A0
三级文本(Tertiary text)#999999#707070
禁用文本(Disabled text)#CCCCCC#505050

6.3 暗色模式下的字重策略

暗色背景下文本会因**光晕效应(halation,浅色光渗入深色背景)**而显得更细,因此需要:

Consider: ├── 正文使用中字重(medium)替代常规字重(regular) ├── 略微增加字母间距(letter-spacing) ├── 在真实 OLED 屏幕上测试 └── 使用比亮色模式略粗的字重

仓库佐证:Dillinger 暗色排版的落地细节Dillinger 在 app/globals.css 中为暗色预览定义了.dark.preview-html { color: #d4d4d4; }——注意它不是纯白 #FFFFFF,而是接近文档推荐的 #E0E0E0 区间,直接呼应"暗色模式禁用纯白"的规则。标题颜色 #e8e8e8、链接保持品牌色 #35D7BB、代码块背景 #2d2d2d 且前景 #d4d4d4,均体现了"降低对比但不牺牲可读性"的暗色排版策略。项目通过darkMode: "class"(tailwind.config.ts)按类切换暗色样式,移动端对应useColorScheme的系统外观监听。


7. 排版反模式:常见错误与 AI 特有错误

7.1 常见错误对照表

错误问题修复
固定字号(Fixed font sizes)无视无障碍使用动态缩放
文本过小(Too small text)不可读最小 14pt/sp
低对比度(Low contrast)阳光下不可见最小 4.5:1
过长行(Long lines)难以追踪最大 60 字符
行高过紧(Tight line height)拥挤、难读最小 1.4×
字号过多(Too many sizes)视觉混乱最多 5–7 个字号
正文全大写(All caps body)难读仅用于标题
白底浅灰(Light gray on white)强光下不可读提高对比度

7.2 AI 生成的排版为何经常出错

AI 生成移动端代码时存在系统性倾向:

AI tends to: ├── 使用固定 px 值而非 pt/sp ├── 跳过 Dynamic Type 支持 ├── 正文过小(12–14px) ├── 忽略行高设置 ├── 使用低对比度的"审美灰" ├── 将桌面尺度原样套用到移动端 └── 跳过在大字号下的测试

最终规则:排版必须可缩放(Typography must SCALE),在最小与最大字号设置下都要测试。

仓库佐证:审计脚本对 AI 反模式的机器化识别mobile_audit.py 的 9.x 扩展检查组几乎逐条对应上述反模式:9.1 检查字号是否偏离 iOS 类型尺度、9.2 检查 Material 排版是否使用 sp 单位、9.3 检查字号是否遵循模块化比例(识别 1.125/1.2/1.25/1.333/1.5 之外的异常比率)、9.4 检查长文本是否缺少最大宽度约束(对应 40–60 字符行宽)、9.5 检查粗体是否过度使用(bold 数量多于 regular 会被标记)。这让排版反模式检查具备了自动化落地手段。


8. 字体加载与性能

8.1 字体文件体积优化

字体文件在移动端是明显的性能负担:

Font file sizes matter on mobile: ├── 完整字体: 每个字重 100–300KB ├── 子集化(拉丁文): 每个字重 15–40KB ├── 可变字体: 100–200KB(覆盖全部字重)

推荐做法:

├── 子集化到需要的字符(Subset to needed characters) ├── 使用 WOFF2 格式 ├── 最多 2–3 个字体文件 ├── 考虑可变字体(variable fonts) ├── 合理缓存字体

8.2 加载策略:四步法

1. SYSTEM FONT FALLBACK(系统字体回退) 先显示系统字体 → 自定义字体加载完成后替换 2. FONT DISPLAY SWAP font-display: swap(CSS 声明) 3. PRELOAD CRITICAL FONTS(预加载关键字体) 预加载首屏(above the fold)需要的字体 4. DON'T BLOCK RENDER(不要阻塞渲染) 不要为了等字体而延迟内容显示

仓库佐证:零字体加载开销的 Web 端策略Dillinger 作为一个以编辑效率为核心的应用,其 tailwind.config.ts 声明的字体栈首项(Source Sans Pro、Georgia、Ubuntu Mono)即使未能加载,也会立即回退到系统字体,天然实现了"系统字体先行、自定义字体渐进增强"的策略——这正是"不阻塞渲染 + 系统回退"在 Web 平台的等价实现。对移动端开发者而言,这条策略对应 SwiftUI 的.font(.custom(..., relativeTo: ...))与 Compose 的FontFamily回退参数。


9. 发布前排版检查清单

9.1 任何文本设计开始之前

  • 正文 ≥ 16px/pt/sp?
  • 行高 ≥ 1.4?
  • 行长 ≤ 60 字符?
  • 定义了类型尺度(最多 5–7 个字号)?
  • 使用 pt(iOS)或 sp(Android)?

9.2 发布之前

  • iOS Dynamic Type 已测试?
  • Android 在 200% 字体缩放下已测试?
  • 暗色模式对比度已检查?
  • 阳光下可读性已测试?
  • 所有文本都有正确的层级?
  • 自定义字体有回退方案?
  • 长文本可正常滚动?

落地建议:把清单变成自动化审计仓库提供的 mobile_audit.py 可以帮你把大部分检查项自动化。其用法(见脚本 main 函数)为:

python scripts/mobile_audit.py <project_path> # 输出人类可读报告 python scripts/mobile_audit.py <project_path> --json # 输出 JSON 报告,便于 CI 集成

脚本自动识别 React Native / Flutter 文件(通过 import 特征),跳过 node_modules 等目录,输出 ISSUES(硬性问题,如 ScrollView+map、缺 keyExtractor、明文存 token)与 WARNINGS(建议项,如固定字号无缩放、缺 React.memo、无暗色模式支持)两级报告,其中排版相关检查覆盖系统字体、文本缩放、行高、字号边界、模块化比例、行宽与字重分布(脚本头部注释 mobile_audit.py 列出了完整的检查矩阵)。退出码非零即表示存在硬性问题,可直接挂入 CI 门禁。


10. 快速参考

10.1 排版令牌(Typographic Tokens)

// iOS(SwiftUI 内建样式) .largeTitle // 34pt, Bold .title // 28pt, Bold .title2 // 22pt, Bold .title3 // 20pt, Semibold .headline // 17pt, Semibold .body // 17pt, Regular .subheadline // 15pt, Regular .footnote // 13pt, Regular .caption // 12pt, Regular // Android(Material 3 文本角色) displayLarge // 57sp headlineLarge // 32sp titleLarge // 22sp bodyLarge // 16sp labelLarge // 14sp

10.2 最小字号速查

Body: 14–16pt/sp(推荐 16) Secondary: 12–13pt/sp Caption: 11–12pt/sp 任何文本: 不得小于 11pt/sp

10.3 行高速查

Headings: 1.1–1.3 Body: 1.4–1.6 Long text: 1.5–1.75

结语:排版即界面

原文档在结尾给出了移动端排版设计的最终判据:如果用户读不懂你的文本,你的应用就是坏的。排版不是装饰——它是主界面(Typography isn't decoration—it's the primary interface)。要在真实设备、真实光照、无障碍设置开启的状态下测试。

将这份指南落到 Dillinger 仓库的语境中可以看到一条完整的证据链:设计文档 mobile-typography.md 定义原则 → 前端排版文档 typography-system.md 给出模块化比例的生成方法 → 审计脚本 mobile_audit.py 将原则量化为可自动执行的检查 → Web 端实现 tailwind.config.ts 与 app/globals.css 提供了"系统字体回退栈 + 宽松行高 + 暗色米白文本"的真实范例。无论你正在构建 React Native、Flutter 还是原生应用,都可以以此为模板:定义类型尺度 → 锚定系统缩放 → 通过审计 → 在极端字号下测试,让排版真正成为用户可读、可缩放、可访问的界面基础设施。

  • 前端
  • 开发工具

【免费下载链接】dillinger

The last Markdown editor, ever.

项目地址:https://gitcode.com/gh_mirrors/di/dillinger
点击查看免费下载

相关推荐

上一篇:Windows窗口置顶神器:3分钟解锁高效多任务工作流
下一篇:猫抓插件终极教程:三步轻松下载网页中的任何视频资源

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询