移动开发中的连字 — 符号连接的基础与应用

作者: IT Sectr 发布日期: 2026-07-24 阅读时间: 9 分钟

连字 是将两个或多个字符图形化连接成一个排版符号,以改善文本的可读性和美观性。经典示例包括 fi、fl、ff、ffi 等组合 — 其中字母 f 的突出部分与相邻字符融合,防止视觉冲突。在现代移动和Web开发中,连字通过 OpenType 功能在字体级别进行管理,并在 iOS、Android 和浏览器中得到支持。根据 MDN Web Docs,CSS 属性 font-variant-ligatures 允许开发者启用和禁用不同类型的连字:标准连字、 discretionary(装饰性)连字和上下文连字。

要点

  • 连字 — 将多个字符合并为一个图形元素以改善可读性
  • 标准连字(fi、fl、ff)默认在专业字体中启用
  • Discretionary 连字(ct、st、sp) — 装饰性,可选择性启用
  • 在 iOS 上通过 UIFontDescriptor 的 featureSettings 管理 OpenType 功能
  • 在编程字体中,连字用于组合运算符:!=、>=、->、=>

排版中的连字是什么

连字 是一种排版技术,其中两个或多个字符被替换为一个专门设计的符号。连字的主要目的是消除相邻字符之间的视觉冲突并改善文本感知。例如,在 fi 组合中,字母 f 的上部突出与字母 i 的点相撞 — 连字将它们合并为一个优雅的符号。

连字分为必需(标准)和可选(装饰性)两种。标准连字 是大多数字体中出现的组合:fi、fl、ff、ffi、ffl。它们被认为是高质量排版所必需的,默认在字体中启用。根据 OpenType 规范,标准连字使用 'liga' 标签编码,并且应在每个专业字体中启用。

视觉效果:没有连字时,fi 组合看起来像两个带有不期望接触的独立字符。使用连字后 — 像一个和谐的符号。这种差异在大尺寸(标题、标志)和具有大量重复组合的文本(例如,在德语中的 häufigen Buchstabenkombinationen)中尤为明显。

连字类型:标准、discretionary、上下文

OpenType 字体支持多种类型的连字,每种都有其自己的标签和用途。标准(标签 'liga')— 默认在字体中启用的必需连字。它们改善可读性,不应无故禁用。包含 fi、fl、ff、ffi、ffl 等组合以及其他特定于字体的组合。

Discretionary 连字(标签 'dlig')— 装饰性连字,根据设计师的判断可选择性启用。它们不是可读性必需的,用于文本样式化:ct、st、sp、Th、Qu 等。Discretionary 连字通常出现在具有历史或书法特征的字体中 — 例如在 Garamond 或 Adobe Caslon 中。警告:过多的 discretionary 连字会降低可读性,特别是对于有阅读障碍的用户。

上下文连字(标签 'clig')— 取决于字符环境的连字。它们仅在特定条件下应用:如果字符位于单词的开头或结尾,在特定标点符号之后等。上下文连字是高级 OpenType 功能,并非所有字体都支持。历史连字(标签 'hlig')— 模仿旧式印刷书籍样式的过时连字(long s、&)。很少使用,仅用于历史或样式化文本。

连字类型OpenType 标签示例默认
标准ligafi、fl、ff、ffi启用
Discretionarydligct、st、sp、Th禁用
上下文clig取决于位置启用
历史hliglong s、ct(历史)禁用

罕见类型:还有用于数学排版的连字(用于数学符号的标签 'dlig')和首字母连字(drop caps)— 但它们不用于界面排版,仅由专业字体支持。

连字的历史:从金属排字到数字字体

连字早在数字排版之前就已出现 — 早在 15 世纪的金属排字时代。印刷商约翰内斯·谷登堡在其 42 行圣经的行中使用连字以节省空间。每个字母都是一个物理金属块,将两个字符合并为一个字母节省了铅料并简化了排版。标准连字 fi、fl、ffi、ffl 是那个时代的遗产。

照相排字(20 世纪)中,连字失去了其实际功能,但作为高质量排版的美学元素保留了下来。字体设计师继续将连字纳入其字体中,因为它们已成为专业性和注重细节的标志。在数字字体时代(PostScript、TrueType),连字作为独立的字形通过程序替换实现。

OpenType(1996 年) 是一场革命:它引入了 GSUB(字形替换表)机制,可在无需用户干预的情况下自动将字符序列替换为连字。GSUB 支持上下文替换、条件和后备变体。这使得字体可以拥有数百个通过标签启用/禁用的连字。现代字体 — SF Pro、Roboto、Inter — 在所有平台上支持 OpenType 连字:iOS、Android、macOS、Windows、Web。

在 iOS 上通过 UIFontDescriptor 实现连字

在 iOS 上,可以通过 UIFontDescriptor 使用 featureSettings 属性来管理连字。此属性接受一个字典数组,每个字典描述一个 OpenType 功能。通过描述符管理连字是控制单个连字类型而不影响字体其他 OpenType 功能的唯一方法。

swift
let descriptor = UIFontDescriptor.preferredFontDescriptor(
    withTextStyle: .body
)

// 启用 discretionary 连字
let ligatureDescriptor = descriptor.addingAttributes([
    .featureSettings: [
        [
            UIFontDescriptor.FeatureIdentifier: kLigaturesType,
            UIFontDescriptor.TypeIdentifier: kCommonLigaturesOnSelector
        ]
    ]
])

let font = UIFont(
    descriptor: ligatureDescriptor,
    size: 17
)

NSAttributedString 也支持 ligature: NSNumber 属性。值为 0 — 禁用所有连字,1 — 启用标准连字(默认),2 — 启用所有连字(包括 discretionary)。然而,NSAttributedString 中的 ligature 属性不提供对连字类型的精细控制 — 仅为全局启用/禁用。对于选择性管理,使用带有 featureSettings 的 UIFontDescriptor。

SwiftUI 不提供直接的连字修饰符。要在 SwiftUI 中管理连字,请通过 UIFontDescriptor 创建具有所需设置的 UIFont,并通过 Font(descriptor:size:) 使用它。或者 — 在 AppKit/UIKit 视图中对 NSMutableAttributedString 使用带有 .ligature 属性的 AttributedString(iOS 15+)。

swift
// 通过 AttributedString 使用自定义连字的 SwiftUI
var attributedText: AttributedString {
    var text = AttributedString(
        "Effective typography with ligatures"
    )

    // 为整个文本启用所有连字
    text.ligature = .all

    return text
}

var body: some View {
    Text(attributedText)
}

在 CSS 和 Android 中管理连字

在 Web 上,连字通过 CSS 属性 font-variant-ligatures 管理,它接受关键字:common-ligatures(标准启用)、no-common-ligatures(标准禁用)、discretionary-ligatures、no-discretionary-ligatures、contextual、no-contextual。该属性自 2015 年起得到所有现代浏览器的支持。默认情况下,浏览器启用标准和上下文连字。

css
/* Disable all ligatures for monospace */
code, pre {
    font-variant-ligatures: none;
}

/* Enable discretionary ligatures for headings */
.title-fancy {
    font-variant-ligatures:
        common-ligatures
        discretionary-ligatures
        contextual;
}

Android 没有用于管理连字的直接 API。在 Android 中,连字在字体和 Minikin 渲染引擎(Android 10+)级别进行管理。如果字体包含 OpenType GSUB 表,连字会自动应用。要在 Android 中禁用连字,使用通过 Typeface.Builder 创建的自定义 Typeface,或进行文本预处理(在显示前替换字符)。限制:在低于 10 的 Android 版本上,连字可能在某些 TTF 字体上无法正常工作。

底层控制:在所有平台上,可以使用带有 font-feature-settings 参数的 CSS @font-face 来管理 OpenType 功能。此方法提供对任何 OpenType 标签的访问,包括连字。示例:font-feature-settings: 'liga' 1, 'dlig' 1。然而,font-feature-settings 是底层语法,MDN 建议使用 font-variant-ligatures 作为更高层的替代方案。

编程字体中的连字

一类特殊的连字 — 编程连字,它将运算符和代码符号组合成更易读的符号。编程字体如 Fira Code、JetBrains Mono、Cascadia Code 包含常见运算符的 discretionary 连字:!=(变为 ≠)、>=(变为 ≥)、->(变为箭头)、=>(变为粗箭头)、===(变为三重等号)。

编程连字在开发者社区中是一个有争议的话题。支持者认为连字加快了代码阅读速度,因为运算符被视为统一的概念。研究(Kera 等人,PLATEAU 2020)表明连字不影响代码阅读速度,但主观上受到 67% 开发者的喜爱。反对连字的人指出它们会扭曲代码:!= 符号在编辑器中显示为 ≠,但在文本文件中存储为两个字符,这在协作时可能会造成混淆。

技术实现:编程连字是 discretionary OpenType 连字(标签 'dlig')。它们默认禁用,在代码编辑器中通过字体设置启用。使用此类字体的开发者必须配置编辑器以启用 discretionary 连字。在终端(iTerm2、Windows Terminal)中,连字也通过字体设置得到支持。兼容性:并非所有编辑器和终端都支持 OpenType 连字。在选择字体之前,请检查与您的工具的兼容性。

kotlin
// 示例:JetBrains Mono 中的运算符连字
val isEqual = a != b  // != 渲染为 ≠
val arrow = x -> x + 1  // -> 渲染为 →
val range = 1 .. 10  // .. 渲染为范围

流行的编程连字字体:Fira Code(第一个具有连字的流行字体,2015 年)、JetBrains Mono(针对代码阅读优化,2020 年)、Cascadia Code(来自微软,2019 年)、Iosevka(具有模块化连字系统的可配置字体)。每种字体都有自己的连字集 — 从 50 到 150+ 个替换。建议:从 Fira Code 或 JetBrains Mono 开始 — 它们在编辑器和 IDE 中具有最佳支持。

常见问题

如何在 iOS 上禁用连字?

在 NSAttributedString 中设置 ligature = 0 属性,或使用带有 kCommonLigaturesOffSelector 的 UIFontDescriptor。在 SwiftUI 中 — 使用 .ligature = .disabled 创建 AttributedString。

连字和字距调整有什么区别?

连字 用一个新的符号替换两个字符,改变其形状。字距调整 调整字符之间的间距,不改变其形状。连字是图形连接,字距调整是空间校正。

Android 支持连字吗?

是的,从 Android 10(API 29)开始。Minikin 渲染完全支持 OpenType GSUB 表。在较早版本上,支持取决于设备制造商和字体引擎版本。

值得在应用程序界面中使用连字吗?

对于主要文本,标准连字(fi、fl、ff)足够了 — 它们改善可读性且对用户不可见。仅在标题或装饰性文本中使用 discretionary 连字,因为它们会降低长文本的可读性。

为什么代码中的连字不在所有编辑器中显示?

编辑器必须支持 OpenType 标签 'dlig' 并能显示 discretionary 连字。VS Code、IntelliJ IDEA、Sublime Text 支持。旧终端和编辑器(nano、无 GUI 的 vim)— 不支持。检查编辑器设置:启用 font-ligatures。

总结

  • 连字 — 将多个字符合并为一个图形元素,用于美观和可读性
  • 标准连字(fi、fl、ff)默认在专业字体中启用
  • Discretionary 连字(ct、st、sp) — 装饰性,通过 CSS font-variant-ligatures 启用
  • 在 iOS 上通过 UIFontDescriptor 的 featureSettings 或 ligature 属性管理
  • 在 Web 上通过 font-variant-ligatures 或 font-feature-settings('liga'、'dlig')管理
  • 编程连字(Fira Code、JetBrains Mono)组合运算符:!=、>=、->
  • 对于界面排版,仅使用标准连字 — discretionary 会降低可读性

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读