Pretext Layout
Overview
Use Pretext to measure multiline text in browser environments without paying repeated DOM reflow costs in the hot path. Prefer it when text width changes often and you need stable height or per-line geometry from cached measurements.
Workflow
- 1. Confirm the runtime first.
- Treat Pretext as browser-first.
- If the task is pure Node or CLI with no
OffscreenCanvas and no
document, do not promise direct runtime support.
- 2. Match the API to the job.
- Use
prepare() plus
layout() for height and line-count measurement.
- Use
prepareWithSegments() plus
layoutWithLines(),
walkLineRanges(), or
layoutNextLine() for custom rendering.
- 3. Sync layout inputs with real styles.
- Read
font and
line-height from the target element or design token source.
- Wait for
document.fonts.ready before trusting measurements when web fonts are involved.
- 4. Cache aggressively.
- Prepare once per
(text, font, whiteSpace, locale) input.
- Reuse the prepared handle across width changes.
- 5. Verify against the real UI when accuracy matters.
- Compare a few representative strings against live DOM heights.
- Include multilingual, emoji, and narrow-width cases if the feature depends on them.
Decision Guide
- - Reach for
prepare() plus layout() when the user needs block height, resize performance, virtualization, scroll anchoring, or pre-measuring text before render. - Reach for
prepareWithSegments() plus rich line APIs when the user needs custom line drawing, canvas text, SVG text, shrink-wrap width discovery, or variable line widths. - Reach for ordinary DOM measurement instead when the task depends on CSS behaviors Pretext does not aim to cover fully.
Core Rules
- - Do not claim server-side support unless the target environment actually provides a compatible canvas context.
- Keep
font and lineHeight aligned with the real UI; measurement errors usually come from mismatched inputs, not from the layout call itself. - Avoid
system-ui for accuracy-sensitive flows on macOS; prefer named fonts. - Treat
prepare() as the expensive step and layout() as the hot path. - When working with textarea-like content, pass
{ whiteSpace: 'pre-wrap' } explicitly.
Implementation Checklist
- - Identify the exact text source, target width source, font source, and line-height source.
- Decide whether the feature only needs height or also needs per-line data.
- Cache prepared handles instead of calling
prepare() on every resize. - Add a small verification path that compares Pretext output with live DOM for representative samples.
- Document any unsupported CSS or runtime assumptions close to the integration point.
Scripts
- - Run
scripts/scaffold_browser_demo.py --out <dir> when you need a minimal browser starter wired to @chenglou/pretext. - Use the scaffold as a disposable starting point; adapt
font, line-height, white-space mode, and UI markup to the real project after generation.
References
- - Read
references/browser-integration.md for the common browser setup pattern and a reusable measurement loop. - Read
references/usage-patterns.md when choosing between the simple and rich APIs. - Read
references/caveats.md before answering questions about accuracy, fonts, white-space, emoji, bidi behavior, or non-browser runtimes. - Read
references/project-examples.md for portable integration patterns you can adapt to any browser-based app or AI CLI workspace.
Pretext 布局
概述
使用 Pretext 在浏览器环境中测量多行文本,无需在热路径中重复支付 DOM 回流成本。当文本宽度频繁变化且需要从缓存测量中获取稳定高度或逐行几何信息时,优先选择此方案。
工作流程
- 1. 首先确认运行时环境。
- 将 Pretext 视为浏览器优先工具。
- 如果任务纯粹是 Node 或 CLI 环境,没有 OffscreenCanvas 和 document,则不要承诺直接运行时支持。
- 2. 根据需求匹配 API。
- 使用 prepare() 加 layout() 进行高度和行数测量。
- 使用 prepareWithSegments() 加 layoutWithLines()、walkLineRanges() 或 layoutNextLine() 进行自定义渲染。
- 3. 使布局输入与实际样式同步。
- 从目标元素或设计标记源读取 font 和 line-height。
- 涉及网络字体时,等待 document.fonts.ready 后再信任测量结果。
- 4. 积极使用缓存。
- 对每组 (text, font, whiteSpace, locale) 输入只准备一次。
- 在宽度变化时复用已准备的处理句柄。
- 5. 当精度重要时,对照实际 UI 进行验证。
- 将几个代表性字符串与实时 DOM 高度进行比较。
- 如果功能依赖多语言、表情符号和窄宽度情况,请包含这些测试用例。
决策指南
- - 当用户需要块高度、调整大小性能、虚拟化、滚动锚定或在渲染前预测量文本时,使用 prepare() 加 layout()。
- 当用户需要自定义行绘制、画布文本、SVG 文本、收缩包裹宽度发现或可变行宽时,使用 prepareWithSegments() 加丰富的行 API。
- 当任务依赖于 Pretext 不打算完全覆盖的 CSS 行为时,改用常规 DOM 测量。
核心规则
- - 除非目标环境实际提供兼容的画布上下文,否则不要声称支持服务器端。
- 保持 font 和 lineHeight 与实际 UI 一致;测量误差通常来自输入不匹配,而非布局调用本身。
- 在 macOS 上对精度敏感流程避免使用 system-ui;优先使用命名字体。
- 将 prepare() 视为昂贵步骤,将 layout() 视为热路径。
- 处理类似文本区域的内容时,显式传递 { whiteSpace: pre-wrap }。
实现检查清单
- - 确定确切的文本源、目标宽度源、字体源和行高源。
- 决定功能是只需要高度还是也需要逐行数据。
- 缓存已准备的处理句柄,而不是在每次调整大小时调用 prepare()。
- 添加一个小的验证路径,将 Pretext 输出与实时 DOM 的代表性样本进行比较。
- 在集成点附近记录任何不支持的 CSS 或运行时假设。
脚本
- - 当需要连接到 @chenglou/pretext 的最小浏览器启动器时,运行 scripts/scaffoldbrowserdemo.py --out 。
- 将脚手架作为一次性起点使用;生成后根据实际项目调整 font、line-height、空白模式和 UI 标记。
参考资料
- - 阅读 references/browser-integration.md 了解常见浏览器设置模式和可复用的测量循环。
- 在简单 API 和丰富 API 之间选择时,阅读 references/usage-patterns.md。
- 在回答关于精度、字体、空白、表情符号、双向文本行为或非浏览器运行时的问题前,阅读 references/caveats.md。
- 阅读 references/project-examples.md 获取可移植的集成模式,适用于任何基于浏览器的应用或 AI CLI 工作空间。