Leading(行距) — 是相邻文本行基线之间的距离,直接决定阅读舒适度。该术语源自物理印刷字体:在行之间插入铅条(lead strips)以增加间距。在现代移动开发中,行距通过iOS中NSAttributedString的lineSpacing和lineHeightMultiple以及Android中TextView的lineSpacing来实现。根据Apple NSMutableParagraphStyle 文档,行间距以点为单位设置,可与行高倍数结合使用。
要点
Leading(行距)(读作“勒丁”)— 是排版中相邻行基线之间的垂直距离。基线 — 是文本字符所在的不可见线条。行距越大,行与行之间的排列越自由。在数字排版中,行距通常被称为行间距或行高。
从历史上看,这个术语出现在金属排版时代:排字工人会在行之间插入细铅条以增加间距。在现代字体中,行距定义为字体大小的比例。 系统默认值 是 1.2(字体大小的 120%),但对于长文本和移动界面,建议使用更大的值。根据 Material Design 排版指南,Web和移动界面的最佳行高为主要文本的 1.4-1.5。
行距与行间距的区别:行距 — 从基线到基线的完整距离,行间距 — 一行底部边界与下一行顶部边界之间的距离。在大多数移动API(iOS NSParagraphStyle、Android TextView)中,使用的正是行间距作为自然行高之上的额外间距。在计算总行间距时需要考虑这一点。
选择 最佳行距 取决于几个因素:字体大小、行长、使用场景和受众。对于行长为 40-60 个字符的典型移动界面,建议行距为字体大小的 1.4 到 1.6。短行(标签、按钮)可以使用较小的行距 — 1.0-1.2。长文本(文章、描述)— 更大的行距,可达 1.8 以获得最大可读性。
实验数据:威奇塔州立大学软件可用性实验室的研究表明,在相同行宽下,行距 1.5 比行距 1.0 的阅读速度提高 7.5%。对于有阅读障碍的用户,最佳行距更高 — 可达 1.8。这些数据得到 WCAG 2.2 建议的确认,该建议要求能够在不丢失内容的情况下将行间距增加到 1.5。
字体的影响:具有高 x-height(小写字母相对高度)的字体比低 x-height 的字体需要更大的行距。例如,Helvetica(高 x-height)建议正文行距 1.5,而 Didot(低 x-height)— 1.3。这是因为在高 x-height 下,在相同的行间距下,行在视觉上会更快地融合。
| 场景 | 推荐行距 | iOS 示例 |
|---|---|---|
| 标题 (24-36pt) | 1.0 — 1.2 | lineHeightMultiple: 1.1 |
| 正文 (14-18pt) | 1.4 — 1.6 | lineHeightMultiple: 1.5 |
| 小号文本 (10-13pt) | 1.3 — 1.5 | lineHeightMultiple: 1.4 |
| 文章和长内容 | 1.5 — 1.8 | lineHeightMultiple: 1.6 |
| 无障碍性(阅读障碍) | 1.6 — 2.0 | lineHeightMultiple: 1.8 |
在iOS中,行间距通过 NSMutableParagraphStyle 类管理,该类包含两个关键属性:lineSpacing(以点为单位的行间额外间距)和 lineHeightMultiple(行高倍数)。这些属性协同工作:总行高计算为字体的自然高度乘以 lineHeightMultiple 加上 lineSpacing。
let paragraphStyle = NSMutableParagraphStyle()
// 方法 1:行高倍数
paragraphStyle.lineHeightMultiple = 1.5
// 方法 2:行之间额外间距
paragraphStyle.lineSpacing = 4.0
// 通过 NSAttributedString 应用
let attributedText = NSAttributedString(
string: "Text with custom line spacing",
attributes: [
.paragraphStyle: paragraphStyle
]
)
lineHeightMultiple — 是首选方式,因为它会在字体大小改变时自动缩放。lineSpacing 以绝对点设置,不会缩放,在使用 Dynamic Type 时可能导致不一致。根据 Apple 文本编程指南,对于无障碍兼容的界面,请将 lineHeightMultiple 与 UIFontMetrics 结合使用。
SwiftUI 为 Text 和 VStack 提供 .lineSpacing() 修饰符。与 UIKit 不同,在 SwiftUI 中行间距以点为单位设置,没有内置倍数。要实现倍数,开发人员需要根据字体大小手动计算行间距。 限制:SwiftUI 不直接支持 lineHeightMultiple — 使用 .lineSpacing(CGFloat) 并传入计算值。
struct LeadingTextView: View {
let fontSize: CGFloat = 17
var lineSpacing: CGFloat {
fontSize * 0.5 // 字体大小的 50%
}
var body: some View {
Text("行间距")
Text("1.5 倍")
.lineSpacing(lineSpacing)
.font(.system(size: fontSize))
}
}
在Android中,行间距通过两个 TextView 属性设置: lineSpacingExtra(以 px 为单位的额外间距)和 lineSpacingMultiplier(行高倍数,默认为 1.0)。与 iOS 类似,倍数在字体大小改变时缩放,而 extra 是绝对值。对于无障碍兼容的界面,建议使用倍数。
// 在 XML 布局中
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Text with line spacing"
android:lineSpacingExtra="4dp"
android:lineSpacingMultiplier="1.5"
android:textSize="16sp" />
// 在 Kotlin 中以编程方式
val textView = findViewById<TextView>(R.id.contentText)
textView.setLineSpacing(
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
4f,
resources.displayMetrics
),
1.5f
)
Compose — 现代 Android UI 框架 — 在 TextStyle 修饰符中使用 lineHeight 参数。与 XML 方法不同,在 Compose 中 lineHeight 设置为以 sp 为单位的完整行高(默认为 fontSize * 1.2)。要设置倍数,开发人员将 lineHeight 指定为 fontSize 的百分比: 示例:TextStyle(fontSize = 16.sp, lineHeight = 24.sp) 给出倍数 1.5。
限制:在 Android API 28 之前,lineSpacingExtra 和 lineSpacingMultiplier 在某些字体上无法正常工作,特别是自定义字体 (TTF/OTF)。建议在真实设备上测试,并注意 systemTextView 默认使用 lineSpacingMultiplier 1.0 — 没有额外间距。对于 ScrollView 中的长文本,请显式设置行间距。
在Web中,行间距通过 CSS 属性 line-height 设置,该属性可以是数字(倍数)、百分比值、长度单位 (px, em) 或关键字 normal。数字倍数 — 是首选方式,因为它会被继承并根据子元素的字体大小进行缩放。normal 值对应大多数字体的约 1.2。
/* Numerical multiplier (recommended) */
body {
font-size: 16px;
line-height: 1.5;
}
/* Percentage value */
.article-content {
line-height: 150%;
}
/* Fixed value (does not scale) */
.small-text {
font-size: 12px;
line-height: 18px;
}
数字倍数与 em:line-height: 1.5 和 line-height: 1.5em 是不同的东西。数字倍数作为计算值被继承,并根据每个子元素的 font-size 重新计算。em 作为基于父元素 font-size 的固定计算值被继承。这是一个关键区别:当 font-size: 20px 嵌套在 font-size: 16px 内时,line-height: 1.5 给出 30px,而 line-height: 1.5em — 24px(来自父元素)。 建议:始终使用数字倍数。
尽管 API 不同,但行间距配置的原则在所有平台上都是相同的。 倍数 (multiplier) 在字体大小改变时缩放,对无障碍友好。 绝对值 (spacing) 不缩放,在使用 Dynamic Type 或大文本设置时可能导致问题。
跨平台策略:在设计系统中将 lineHeight 设置为 fontSize 的倍数。例如,在设计令牌中:line-height-body = 1.5,line-height-heading = 1.1。每个平台通过自己的 API 实现此倍数:iOS — lineHeightMultiple,Android — lineSpacingMultiplier,Web — line-height: 1.5。这保证了所有平台上相同的视觉效果。
| 平台 | 倍数 API | 间距 API |
|---|---|---|
| iOS UIKit | NSParagraphStyle.lineHeightMultiple | NSParagraphStyle.lineSpacing |
| iOS SwiftUI | .lineSpacing(手动计算) | .lineSpacing(CGFloat) |
| Android XML | android:lineSpacingMultiplier | android:lineSpacingExtra |
| Android Compose | TextStyle.lineHeight(以 sp 为单位) | TextStyle.lineHeight |
| Web CSS | line-height: {数字} | line-height: {px/em} |
重要细节:在 iOS 中,lineHeightMultiple 应用于完整的行高(包括字体的 ascender + descender),而在 Android 中,lineSpacingMultiplier 应用于由 Minikin 渲染引擎计算的行高。在实践中,这导致在相同倍数值下视觉行距存在微小差异。要实现像素级完美匹配,请使用带有平台校正的绝对值。
常见问题
行距 — 从一行基线到下一行基线的完整距离。 行间距 — 添加到自然行高之间的额外间距。在 iOS 中,lineSpacing 正是额外间距,而不是完整高度。
为了符合 WCAG 2.2,正文使用 line-height 1.5。有阅读障碍和视力障碍的用户阅读行距 1.6 到 1.8 的文本效果更好。确保用户可以在不丢失内容的情况下增加行间距。
SwiftUI 使用自己的渲染引擎,其中 lineSpacing 是以点为单位且没有内置倍数的行间距。在 UIKit 中,lineHeightMultiple 随字体大小缩放。为了在 SwiftUI 中保持一致性,计算 lineSpacing 为 fontSize * 0.5(对应倍数 1.5)。
对 FPS 没有直接影响,但更大的行距会增加 内容高度,从而增加 UICollectionView/RecyclerView 中的单元格数量,这间接影响性能。对于包含数千个元素的列表,请在设计系统中优化行距。
使用公式: line-height = font-size + (font-size * multiplier)。对于 16pt 字体,倍数为 1.5:16 + (16 * 0.5) = 24pt。在实际文本上目视检查 — 不同的字体需要单独调整。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。