Leading (lê-đinh) — là khoảng cách giữa các đường cơ sở của các dòng chữ liền kề, quyết định trực tiếp sự thoải mái khi đọc. Thuật ngữ này xuất phát từ các con chữ in ấn vật lý: các dải chì (lead strips) được chèn giữa các dòng để tăng khoảng cách. Trong phát triển di động hiện đại, leading được triển khai qua lineSpacing và lineHeightMultiple trên iOS trong NSAttributedString và qua lineSpacing trên Android trong TextView. Theo Tài liệu NSMutableParagraphStyle của Apple, khoảng cách dòng được xác định bằng điểm và có thể kết hợp với hệ số nhân chiều cao dòng.
Điểm chính
Leading (đọc là “lê-đinh”) — là khoảng cách dọc giữa các đường cơ sở của các dòng liền kề trong typography. Đường cơ sở là đường vô hình mà trên đó các ký tự văn bản được đặt. Leading càng lớn, các dòng càng được sắp xếp tự do hơn so với nhau. Trong typography kỹ thuật số, leading thường được gọi là giãn dòng hoặc chiều cao dòng.
Về mặt lịch sử, thuật ngữ này xuất hiện trong thời đại in ấn kim loại: thợ sắp chữ chèn các dải chì mỏng giữa các dòng để tăng khoảng cách. Trong phông chữ hiện đại, leading được xác định như một tỷ lệ so với kích thước phông chữ. Giá trị hệ thống mặc định là 1.2 (120% kích thước phông chữ), nhưng đối với văn bản dài và giao diện di động, giá trị lớn hơn được khuyên dùng. Theo Nguyên tắc Typography của Material Design, chiều cao dòng tối ưu cho giao diện web và di động là 1.4-1.5 đối với văn bản chính.
Sự khác biệt giữa leading và giãn dòng: leading là khoảng cách tổng thể từ đường cơ sở này đến đường cơ sở kia, giãn dòng là khoảng cách giữa ranh giới dưới của một dòng và ranh giới trên của dòng tiếp theo. Trong hầu hết các API di động (iOS NSParagraphStyle, Android TextView), giãn dòng được sử dụng như khoảng cách bổ sung trên chiều cao tự nhiên của dòng. Điều này cần được tính đến khi tính toán tổng khoảng cách dòng.
Việc chọn leading tối ưu phụ thuộc vào nhiều yếu tố: cỡ chữ, độ dài dòng, ngữ cảnh sử dụng và đối tượng. Đối với giao diện di động có độ rộng dòng điển hình 40-60 ký tự, leading 1.4 đến 1.6 cỡ chữ được khuyên dùng. Các dòng ngắn (nhãn, nút) có thể sử dụng leading nhỏ hơn — 1.0-1.2. Văn bản dài (bài viết, mô tả) — leading lớn hơn, lên đến 1.8 để đạt khả năng đọc tối đa.
Dữ liệu thực nghiệm: nghiên cứu từ Phòng thí nghiệm Khả năng sử dụng Phần mềm của Đại học Wichita State cho thấy leading 1.5 làm tăng tốc độ đọc lên 7.5% so với leading 1.0 ở cùng độ rộng dòng. Đối với người dùng mắc chứng khó đọc, leading tối ưu còn cao hơn — lên đến 1.8. Dữ liệu này được xác nhận bởi các khuyến nghị WCAG 2.2, yêu cầu khả năng tăng khoảng cách dòng lên 1.5 mà không mất nội dung.
Ảnh hưởng của kiểu chữ: các phông chữ có x-height cao (chiều cao tương đối của chữ thường) yêu cầu leading lớn hơn các phông chữ có x-height thấp. Ví dụ, Helvetica (x-height cao) khuyên dùng leading 1.5 cho văn bản nội dung, trong khi Didot (x-height thấp) — 1.3. Điều này liên quan đến thực tế là với x-height cao, các dòng hòa trộn trực quan nhanh hơn ở cùng khoảng cách dòng.
| Ngữ cảnh | Leading khuyên dùng | Ví dụ iOS |
|---|---|---|
| Tiêu đề (24-36pt) | 1.0 — 1.2 | lineHeightMultiple: 1.1 |
| Văn bản chính (14-18pt) | 1.4 — 1.6 | lineHeightMultiple: 1.5 |
| Văn bản nhỏ (10-13pt) | 1.3 — 1.5 | lineHeightMultiple: 1.4 |
| Bài viết và longread | 1.5 — 1.8 | lineHeightMultiple: 1.6 |
| Khả năng tiếp cận (chứng khó đọc) | 1.6 — 2.0 | lineHeightMultiple: 1.8 |
Trên iOS, khoảng cách dòng được điều khiển qua lớp NSMutableParagraphStyle, chứa hai thuộc tính chính: lineSpacing (khoảng cách bổ sung giữa các dòng tính bằng điểm) và lineHeightMultiple (hệ số nhân chiều cao dòng). Các thuộc tính này hoạt động cùng nhau: chiều cao dòng cuối cùng được tính là chiều cao tự nhiên của phông chữ nhân với lineHeightMultiple, cộng thêm lineSpacing.
let paragraphStyle = NSMutableParagraphStyle()
// Phương pháp 1: hệ số nhân chiều cao dòng
paragraphStyle.lineHeightMultiple = 1.5
// Phương pháp 2: khoảng cách bổ sung giữa các dòng
paragraphStyle.lineSpacing = 4.0
// Áp dụng qua NSAttributedString
let attributedText = NSAttributedString(
string: "Text with custom line spacing",
attributes: [
.paragraphStyle: paragraphStyle
]
)
lineHeightMultiple — là phương pháp ưu tiên, vì nó tự động co giãn khi kích thước phông chữ thay đổi. lineSpacing được xác định bằng điểm tuyệt đối và không co giãn, điều này có thể dẫn đến không nhất quán khi sử dụng Dynamic Type. Theo Apple Text Programming Guide, đối với giao diện tương thích khả năng tiếp cận, hãy sử dụng lineHeightMultiple kết hợp với UIFontMetrics.
SwiftUI cung cấp bộ sửa đổi .lineSpacing() cho Text và VStack. Khác với UIKit, trong SwiftUI khoảng cách dòng được xác định bằng điểm và không có hệ số nhân tích hợp sẵn. Để triển khai hệ số nhân, nhà phát triển cần tự tính khoảng cách dòng dựa trên kích thước phông chữ. Hạn chế: SwiftUI không hỗ trợ lineHeightMultiple trực tiếp — hãy sử dụng .lineSpacing(CGFloat) với giá trị đã tính toán.
struct LeadingTextView: View {
let fontSize: CGFloat = 17
var lineSpacing: CGFloat {
fontSize * 0.5 // 50% kích thước phông chữ
}
var body: some View {
Text("Giãn dòng")
Text("Hệ số nhân 1.5")
.lineSpacing(lineSpacing)
.font(.system(size: fontSize))
}
}
Trên Android, khoảng cách dòng được xác định qua hai thuộc tính của TextView: lineSpacingExtra (khoảng cách bổ sung tính bằng px) và lineSpacingMultiplier (hệ số nhân chiều cao dòng, mặc định 1.0). Tương tự iOS, hệ số nhân co giãn khi kích thước phông chữ thay đổi, còn extra là giá trị tuyệt đối. Đối với giao diện tương thích khả năng tiếp cận, nên sử dụng hệ số nhân.
// Trong bố cục 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" />
// Lập trình trong Kotlin
val textView = findViewById<TextView>(R.id.contentText)
textView.setLineSpacing(
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
4f,
resources.displayMetrics
),
1.5f
)
Compose — framework UI hiện đại của Android — sử dụng tham số lineHeight trong bộ sửa đổi TextStyle. Khác với cách tiếp cận XML, trong Compose, lineHeight được xác định là chiều cao dòng tổng thể tính bằng sp (mặc định = fontSize * 1.2). Để thiết lập hệ số nhân, nhà phát triển chỉ định lineHeight dưới dạng phần trăm của fontSize: Ví dụ: TextStyle(fontSize = 16.sp, lineHeight = 24.sp) cho hệ số nhân 1.5.
Hạn chế: trên Android đến API 28, lineSpacingExtra và lineSpacingMultiplier hoạt động không chính xác với một số phông chữ, đặc biệt là phông chữ tùy chỉnh (TTF/OTF). Nên kiểm tra trên thiết bị thật và lưu ý rằng systemTextView mặc định sử dụng lineSpacingMultiplier 1.0 — không có khoảng cách bổ sung. Đối với văn bản dài trong ScrollView, bắt buộc phải đặt khoảng cách dòng một cách tường minh.
Trên web, khoảng cách dòng được xác định bởi thuộc tính CSS line-height, có thể là số (hệ số nhân), giá trị phần trăm, đơn vị độ dài (px, em) hoặc từ khóa normal. Hệ số nhân số là phương pháp ưu tiên, vì nó được kế thừa và co giãn theo kích thước phông chữ của các phần tử con. Giá trị normal tương ứng khoảng 1.2 đối với hầu hết các phông chữ.
/* 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;
}
Hệ số nhân số vs em: line-height: 1.5 và line-height: 1.5em là hai khái niệm khác nhau. Hệ số nhân số được kế thừa dưới dạng giá trị đã tính toán và được tính lại cho mỗi phần tử con dựa trên font-size của nó. em được kế thừa dưới dạng giá trị đã tính toán cố định dựa trên font-size của phần tử cha. Đây là sự khác biệt quan trọng: khi font-size: 20px nằm trong font-size: 16px, line-height: 1.5 sẽ cho 30px, trong khi line-height: 1.5em sẽ cho 24px (từ phần tử cha). Khuyến nghị: luôn sử dụng hệ số nhân số.
Mặc dù có API khác nhau, nguyên tắc thiết lập khoảng cách dòng là giống nhau trên tất cả các nền tảng. Hệ số nhân co giãn khi kích thước phông chữ thay đổi và thân thiện với khả năng tiếp cận. Giá trị tuyệt đối (khoảng cách) không co giãn và có thể gây ra sự cố khi sử dụng Dynamic Type hoặc cài đặt văn bản lớn.
Chiến lược đa nền tảng: xác định lineHeight trong hệ thống thiết kế là hệ số nhân của fontSize. Ví dụ, trong token thiết kế: line-height-body = 1.5, line-height-heading = 1.1. Mỗi nền tảng triển khai hệ số nhân này qua API riêng: iOS — lineHeightMultiple, Android — lineSpacingMultiplier, Web — line-height: 1.5. Điều này đảm bảo kết quả trực quan giống nhau trên tất cả các nền tảng.
| Nền tảng | API hệ số nhân | API khoảng cách |
|---|---|---|
| iOS UIKit | NSParagraphStyle.lineHeightMultiple | NSParagraphStyle.lineSpacing |
| iOS SwiftUI | .lineSpacing (tính thủ công) | .lineSpacing(CGFloat) |
| Android XML | android:lineSpacingMultiplier | android:lineSpacingExtra |
| Android Compose | TextStyle.lineHeight (bằng sp) | TextStyle.lineHeight |
| Web CSS | line-height: {số} | line-height: {px/em} |
Sắc thái quan trọng: trên iOS, lineHeightMultiple được áp dụng cho chiều cao dòng đầy đủ (bao gồm ascender + descender của phông chữ), trong khi trên Android, lineSpacingMultiplier được áp dụng cho chiều cao dòng do công cụ kết xuất Minikin tính toán. Trong thực tế, điều này dẫn đến sự khác biệt nhỏ về leading trực quan ở cùng giá trị hệ số nhân. Để khớp pixel hoàn hảo, hãy sử dụng giá trị tuyệt đối với sự điều chỉnh theo nền tảng.
Câu hỏi thường gặp
Leading — là khoảng cách tổng thể từ đường cơ sở của dòng này đến đường cơ sở của dòng tiếp theo. Giãn dòng — là khoảng cách bổ sung giữa các dòng được thêm vào chiều cao tự nhiên của dòng. Trong iOS, lineSpacing chính xác là khoảng cách bổ sung, không phải chiều cao tổng thể.
Để tuân thủ WCAG 2.2, hãy sử dụng line-height 1.5 cho văn bản chính. Người dùng mắc chứng khó đọc và khiếm thị đọc văn bản tốt hơn với leading từ 1.6 đến 1.8. Đảm bảo người dùng có thể tăng khoảng cách dòng mà không mất nội dung.
SwiftUI sử dụng công cụ kết xuất riêng, nơi lineSpacing là khoảng cách giữa các dòng tính bằng điểm, không có hệ số nhân tích hợp sẵn. Trong UIKit, lineHeightMultiple co giãn theo kích thước phông chữ. Để nhất quán trong SwiftUI, hãy tính lineSpacing là fontSize * 0.5 cho hệ số nhân 1.5.
Không có ảnh hưởng trực tiếp đến FPS, nhưng leading lớn hơn làm tăng chiều cao nội dung và do đó tăng số lượng ô trong UICollectionView/RecyclerView, ảnh hưởng gián tiếp đến hiệu suất. Đối với danh sách hàng ngàn phần tử, hãy tối ưu leading trong hệ thống thiết kế.
Sử dụng công thức: line-height = font-size + (font-size * multiplier). Đối với phông chữ 16pt với hệ số nhân 1.5: 16 + (16 * 0.5) = 24pt. Kiểm tra trực quan trên văn bản thực tế — các kiểu chữ khác nhau yêu cầu điều chỉnh riêng.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm