imgrender

文字排版与字体

字体管理和高级文本渲染

字体

imgrender 预设了常用字体。

系统预设字体

imgrender 内预设了以下字体,这些字体可免费商用。

Font FamilyGeneral Font FamilySupported Font WeightSupported Font Style
AlibabaPuHuiTisans-serif100 300 400 500 700 900normal
Alibaba Sans KRsans-serif100 300 400 500 700 900normal
Source Han Serif CNserif200 300 400 500 600 700 900normal
Source Han Serif JPserif200 300 400 500 600 700 900normal
Source Han Serif KRserif200 300 400 500 600 700 900normal
Source Han Sans CNsans-serif100 300 350 400 500 700 900normal
Source Han Sans TWsans-serif100 300 350 400 500 700 900normal
Source Han Sans JPsans-serif100 300 350 400 500 700 900normal
Source Han Sans KRsans-serif100 300 350 400 500 700 900normal
Geistsans-serif100 200 300 400 500 600 700 800 900normal oblique
Geist Monomonospace100 200 300 400 500 600 700 800 900normal
Twemojiemoji不适用不适用

关于字重和字体样式

字重说明:

  • 100 - Thin(极细)
  • 200 - ExtraLight(特细)
  • 300 - Light(细)
  • 400 - Regular(常规)
  • 500 - Medium(中等)
  • 600 - SemiBold(半粗)
  • 700 - Bold(粗)
  • 800 - ExtraBold(特粗)
  • 900 - Black/Heavy(黑体/特粗)

关于斜体:

  • 中日韩(CJK)字体(如思源宋体、思源黑体、阿里巴巴普惠体)通常不包含真正的斜体(italic)字形
  • Geist 字体的 oblique 样式是通过机械倾斜正体字实现的伪斜体
  • 如需中文斜体效果,可使用 CSS 的 transform: skewX() 或 font-style: oblique 实现

字体来源

  • AlibabaPuHuiTi / Alibaba Sans KR - 阿里巴巴设计团队出品,GitHub
  • Source Han Serif - Adobe 开源字体(思源宋体),GitHub
  • Source Han Sans - Adobe 开源字体(思源黑体),GitHub
  • Geist / Geist Mono - Vercel 出品,官网 / GitHub
  • Twemoji - Twitter 开源 Emoji 字体,GitHub

使用字体

使用通用字体名:

<div style="font-family: sans-serif">Hello imgrender</div>

会使用 sans-serif 字体。由于存在多个 sans-serif 字体,具体使用到的字体遵循字体回退机制。

<div style="font-family: serif">Hello imgrender</div>

会使用 serif 字体。由于存在多个 serif 字体,具体使用到的字体遵循字体回退机制。

使用指定字体:

<div style="font-family: Source Han Serif CN">Hello imgrender</div>

指定使用 Source Han Serif CN 字体。

字体回退机制

字体回退(Font Fallback)机制用于在首选字体不可用或不包含所需字符时,自动选择替代字体。imgrender 根据以下规则处理字体回退:

未指定字体时的回退

当没有明确指定 font-family 时,imgrender 会按照系统预设字体表格的顺序依次尝试,直到找到能够渲染当前字符的字体:

<!-- 未指定 font-family -->
<div>Hello 世界 🎉</div>

渲染过程:

  1. Hello - 尝试 AlibabaPuHuiTi,包含拉丁字母,直接渲染
  2. 世界 - AlibabaPuHuiTi 包含中文字符,直接渲染
  3. 🎉 - AlibabaPuHuiTi 不包含 emoji,按表格顺序查找,最终由 Twemoji 渲染

完整回退顺序(按表格从上到下):

AlibabaPuHuiTi → Alibaba Sans KR → Source Han Serif CN → Source Han Serif JP →
Source Han Serif KR → Source Han Sans CN → Source Han Sans TW → Source Han Sans JP →
Source Han Sans KR → Geist → Geist Mono → Twemoji

默认字体的选择

由于 AlibabaPuHuiTi 位于表格首位,且包含中日韩文字和拉丁字母,大多数文本在未指定字体时会直接使用 AlibabaPuHuiTi 渲染。这意味着:

  • 中文、英文、数字默认使用 AlibabaPuHuiTi(无衬线黑体风格)
  • Emoji 默认使用 Twemoji
  • 如需衬线字体或特定风格,请显式指定 font-family

使用通用字体名时的回退

当使用通用字体名(如 sans-serif、serif、monospace、emoji)时,imgrender 会按照系统预设字体表格中的顺序,从上到下查找该类别的第一个可用字体:

通用字体名回退顺序(按表格顺序)
sans-serifAlibabaPuHuiTi → Alibaba Sans KR → Source Han Sans CN → Source Han Sans TW → Source Han Sans JP → Source Han Sans KR → Geist
serifSource Han Serif CN → Source Han Serif JP → Source Han Serif KR
monospaceGeist Mono
emojiTwemoji

示例:

<!-- 使用 sans-serif 时,会优先使用 AlibabaPuHuiTi -->
<div style="font-family: sans-serif">你好世界</div>

<!-- 使用 serif 时,会优先使用 Source Han Serif CN -->
<div style="font-family: serif">你好世界</div>

字符缺失时的回退

当渲染某个字符时,如果当前字体不包含该字符的字形(glyph),系统会按以下顺序查找:

  1. 检查字体列表中的下一个字体 - 如果 font-family 指定了多个字体,依次尝试
  2. 检查同类别的其他字体 - 在同 General Font Family 的预设字体中查找
  3. 跨类别查找 - 尝试其他类别的字体
  4. 使用后备字体 - 最后使用系统默认后备字体

示例:

<!-- 混合文本的回退过程 -->
<div style="font-family: Geist">Hello 世界 🎉</div>

渲染过程:

  1. Hello - Geist 包含拉丁字母,直接渲染
  2. 世界 - Geist 不包含中文,回退到 AlibabaPuHuiTi(首个 sans-serif 中文字体)
  3. 🎉 - 所有文本字体都不包含 emoji,回退到 Twemoji

自定义字体回退列表

你可以在 font-family 中指定多个字体,用逗号分隔,实现自定义的回退顺序:

<div style="font-family: Geist, Source Han Sans CN, sans-serif">Hello 世界</div>

回退顺序:

  1. 优先使用 Geist 渲染拉丁字母
  2. 中文回退到 Source Han Sans CN
  3. 最后使用系统默认 sans-serif

最佳实践

  1. 指定回退字体 - 始终在 font-family 末尾添加通用字体名作为保底
  2. 考虑语言特性 - 混合多语言内容时,明确指定各语言的回退字体
  3. Emoji 处理 - 如需精确控制 emoji 渲染,在字体列表末尾添加 emoji
<div style="font-family: Geist, Source Han Sans CN, Twemoji, sans-serif">
  Hello 世界 🎉
</div>

文字排版

空白控制

默认情况下,连续的空格、制表符和换行符会合并为一个空格,文本会根据可用宽度自动换行。imgrender 不会完全忽略行首尾空白:行首空白可能产生可见偏移,行尾空白也可能增加元素的宽度。请避免在标签内的文本前后加入无意的换行和缩进。

你也可以使用 white-space 属性来控制空白的渲染规则:

属性值合并空白符保留换行符自动换行说明
normal✅❌✅默认行为,连续空白符合并为一个空格,换行符也被合并,文本自动换行
nowrap✅❌❌合并空白符和换行符,但禁止自动换行,文本在同一行内显示
pre❌✅❌保留所有空白符和换行符,禁止自动换行,行为类似 <pre> 元素
pre-line✅✅✅合并空白符但保留换行符,文本自动换行,源码中的换行会被保留
pre-wrap❌✅✅保留所有空白符和换行符,同时允许自动换行,适合显示格式化代码

imgrender 不支持 white-space: break-spaces,使用该值会导致渲染报错。

使用示例

保留源码中的换行和缩进:

<div style="white-space: pre-wrap">第一行文字
  第二行有缩进
第三行无缩进</div>

禁止文本换行:

<div style="white-space: nowrap">这段文字不会自动换行,即使容器宽度不够</div>

关于换行符

在 HTML 中,可以直接在标签内输入换行和缩进。使用 white-space: pre-wrap、pre 或 pre-line 时,源码中的换行会被保留;缩进是否保留取决于所选的 white-space 值。

换行

CSS 的 text-wrap 属性用于控制元素内的文本换行方式。imgrender 支持以下值:

属性值说明
wrap默认值,文本在行尾自动换行,受 word-break 和 overflow-wrap 等属性影响
nowrap禁止自动换行;源码中的显式换行是否保留,取决于 white-space 的空白处理规则
balance平衡换行,自动调整换行位置使每行的字符数尽可能相近,适合标题、段落等短文本
pretty美观换行,可用于段落;实际换行位置取决于文本和可用宽度

balance vs pretty

  • balance 可用于标题、卡片内容等短文本,改善各行长度的平衡
  • pretty 可用于段落,调整换行位置
  • 两者的效果都取决于文本和可用宽度,部分情况下会与普通 wrap 的结果相同

使用示例

平衡换行(适合标题):

<h1 style="text-wrap: balance">
  This is a long title that will be wrapped evenly across lines
</h1>

美观换行(适合段落):

<p style="text-wrap: pretty">
  This is a long paragraph text that benefits from prettier line breaking with
  better typography considerations like preventing orphans.
</p>

禁止自动换行:

<div style="text-wrap: nowrap">这段文本不会自动换行</div>

与 white-space 的关系

在默认空白处理下,text-wrap: nowrap 与 white-space: nowrap 都能让文本保持单行,但两者并不完全等价:

  • white-space: nowrap 会合并空白符和源码中的换行,同时禁止自动换行
  • text-wrap: nowrap 只禁止自动换行,不改变空白符的处理规则;配合 white-space: pre-wrap 或 pre 时,源码中的换行和连续空格仍会保留

如果希望保留空格和显式换行,同时禁止自动换行,可以直接使用 white-space: pre。

文字溢出省略

当容器空间不足以显示完整文本时,可以使用 text-overflow 属性控制溢出文本的显示方式。

text-overflow 属性

属性值说明
clip默认值,不显示省略标记;是否裁剪溢出内容由 overflow 决定
ellipsis在溢出文本末尾显示省略号 ...

自定义 text-overflow 字符串不作为受支持的省略标记,请使用 ellipsis。

生效条件

文本需要实际超出可用空间才会显示省略号。元素应有明确的宽度限制,例如 width、max-width,或受到父级布局的宽度约束。flex-shrink 本身不定义宽度限制。

单行省略通常搭配 white-space: nowrap 使用。在 imgrender 中,text-overflow: ellipsis 在 overflow: visible 下也能生效,并不要求设置 overflow: hidden。如需裁剪元素边界外的内容,可设置 overflow: hidden 或 clip。

imgrender 不支持 overflow: scroll 或 auto,使用这些值会导致渲染报错。

单行文本省略

<div
  style="width: 200px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis"
>
  这是一段很长很长的文本,超出容器宽度时会显示省略号
</div>

多行文本省略

对于多行文本,使用 line-clamp 限制显示行数,并配合 text-overflow: ellipsis 在截断处显示省略号:

<div
  style="width: 300px; line-clamp: 3; text-overflow: ellipsis; overflow: hidden"
>
  这是一段很长很长的文本,当超过三行时会被截断并显示省略号。
  多行省略适用于文章摘要、商品描述等场景。增加文本长度,即可观察截行和省略号的效果。
</div>

截行与省略号

line-clamp 和 -webkit-line-clamp 都能限制显示行数,但单独设置它们不会自动显示省略号。需要省略号时,请同时设置 text-overflow: ellipsis。

imgrender 不支持 display: -webkit-box,使用该值会导致渲染报错。截行时无需设置该值或 -webkit-box-orient。

On this page