Cải thiện tính năng dự phòng phông chữ

Katie Hempenius
Katie Hempenius

Tóm tắt

Bài viết này trình bày chi tiết về tính năng dự phòng phông chữ cũng như các API size-adjust, ascent-override, descent-overrideline-gap-override. Các API này giúp bạn có thể sử dụng phông chữ trên máy để tạo các mặt phông chữ dự phòng gần khớp hoặc khớp chính xác với kích thước của phông chữ trên web. Điều này giúp làm giảm hoặc loại bỏ những thay đổi về bố cục do hoán đổi phông chữ.

Nếu bạn không muốn đọc bài viết này, dưới đây là một số công cụ mà bạn có thể sử dụng để bắt đầu sử dụng các API này ngay lập tức:

Công cụ khung:

  • @next/font: Kể từ 13 Next, next/font sẽ tự động dùng chế độ ghi đè chỉ số phông chữ và size-adjust để cung cấp kiểu dự phòng phông chữ phù hợp.
  • @nuxtjs/fontaine: Kể từ Nuxt 3, bạn có thể sử dụng nuxt/fontaine để tự động tạo và chèn các bản dự phòng phông chữ phù hợp vào các biểu định kiểu mà ứng dụng Nuxt của bạn sử dụng.

Công cụ không phải khung:

  • Fontaine: Fontaine là một thư viện tự động tạo và chèn các bản dự phòng phông chữ có sử dụng cơ chế ghi đè chỉ số phông chữ.
  • Kho lưu trữ này chứa các chế độ ghi đè chỉ số phông chữ cho tất cả các phông chữ do Google Fonts lưu trữ. Bạn có thể sao chép và dán các giá trị này vào biểu định kiểu của mình.

Thông tin khái quát

Phông chữ dự phòng là kiểu phông chữ được dùng khi mặt phông chữ chính chưa được tải hoặc thiếu ký tự cần thiết để hiển thị nội dung trang. Ví dụ: CSS bên dưới cho biết rằng bạn nên dùng bộ phông chữ sans-serif làm phông chữ dự phòng cho "Roboto".

font-family: "Roboto" , sans-serif;

Bạn có thể dùng phông chữ dự phòng để hiển thị văn bản nhanh hơn (tức là bằng cách sử dụng font-display: swap). Do đó, nội dung trang sẽ dễ đọc và hữu ích sớm hơn. Tuy nhiên, trước đây, điều này vẫn khiến bố cục không ổn định: thay đổi bố cục thường xảy ra khi phông chữ dự phòng được hoán đổi cho phông chữ trên web. Tuy nhiên, các API mới được thảo luận dưới đây có thể làm giảm hoặc loại bỏ vấn đề này bằng cách cho phép tạo các mặt phông chữ dự phòng chiếm cùng lượng không gian với phông chữ trên web.

Cải thiện tính năng dự phòng phông chữ

Có 2 phương pháp tạo phông chữ dự phòng "được cải thiện". Phương pháp đơn giản hơn chỉ sử dụng chỉ số phông chữ ghi đè API. Phương pháp phức tạp hơn (nhưng hiệu quả hơn) sử dụng cả chỉ số phông chữ ghi đè API và size-adjust. Bài viết này giải thích cả hai phương pháp này.

Cách hoạt động của chế độ ghi đè chỉ số phông chữ

Giới thiệu

Chế độ ghi đè chỉ số phông chữ cho phép bạn ghi đè độ lên, giảm dần và khoảng cách dòng của phông chữ:

  • Độ cao đo khoảng cách xa nhất mà ký tự của phông chữ mở rộng so với đường cơ sở.
  • Độ xuống đo khoảng cách xa nhất mà ký tự của phông chữ mở rộng bên dưới đường cơ sở.
  • Khoảng cách dòng, còn được gọi là "đầu", đo khoảng cách giữa các dòng văn bản liên tiếp.

Biểu đồ mô tả độ dốc, độ giảm và khoảng cách giữa các dòng của phông chữ.

Bạn có thể dùng chế độ ghi đè chỉ số phông chữ để ghi đè giá trị tăng dần, giảm dần và khoảng cách dòng của phông chữ dự phòng cho khớp với kiểu tăng dần, giảm dần và khoảng cách dòng của phông chữ trên web. Do đó, phông chữ trên web và phông chữ dự phòng được điều chỉnh sẽ luôn có cùng kích thước dọc.

Ghi đè chỉ số phông chữ được sử dụng trong biểu định kiểu như sau:

body {
    font-family: Poppins, "fallback for poppins";
}

@font-face {
    font-family: "fallback for poppins";
    src: local("Times New Roman");
    ascent-override: 105%;
    descent-override: 35%;
    line-gap-override: 10%;
}

Các công cụ được liệt kê ở đầu bài viết này có thể tạo ra các giá trị ghi đè chỉ số phông chữ chính xác. Tuy nhiên, bạn cũng có thể tự tính toán các giá trị này.

Đang tính ghi đè chỉ số phông chữ

Các phương trình sau đây sẽ ghi đè chỉ số phông chữ cho một phông chữ nhất định trên web. Giá trị của quy tắc ghi đè chỉ số phông chữ phải được viết dưới dạng tỷ lệ phần trăm (ví dụ: 105%) thay vì số thập phân.

ascent-override = ascent/unitsPerEm
descent-override = descent/unitsPerEm
line-gap-override = line-gap/unitsPerEm

Ví dụ: đây là các chế độ ghi đè chỉ số phông chữ cho phông chữ Poppins:

/*
Poppins font metrics:
ascent = 1050
descent = 350
line-gap = 100
UPM: 1000
*/

ascent-override: 105%;  /* = 1050/1000 */
descent-override: 35%;  /* = 350/1000 */
line-gap-override: 10%; /* = 100/1000 */

Giá trị của ascent, descent, line-gapunitsPerEm đều đến từ siêu dữ liệu của phông chữ trên web. Phần tiếp theo của bài viết này giải thích cách lấy các giá trị này.

Đọc bảng phông chữ

Siêu dữ liệu của phông chữ (cụ thể là các bảng phông chữ) chứa tất cả thông tin mà bạn sẽ cần để tính toán ghi đè chỉ số phông chữ.

Ảnh chụp màn hình hộp thoại Thông tin về phông chữ trong FontForge. Hộp thoại này hiển thị các chỉ số về phông chữ như "Typo Ascent", "Giảm độ mờ kiểu chữ" và "Khoảng trống dòng kiểu chữ".
Sử dụng FontForge để xem siêu dữ liệu về phông chữ

Sau đây là một số công cụ bạn có thể sử dụng để đọc siêu dữ liệu của phông chữ:

  • fontkit là một công cụ phông chữ được thiết kế cho Node.js. Đoạn mã này cho biết cách sử dụng fontkit để tính toán ghi đè chỉ số phông chữ.
  • Capsize là thư viện định cỡ và bố cục phông chữ. Capsize cung cấp một API để nhận thông tin về nhiều chỉ số phông chữ.
  • fontdrop.info là một trang web cho phép bạn xem bảng phông chữ và các thông tin khác liên quan đến phông chữ trên trình duyệt.
  • Font Forge là trình chỉnh sửa phông chữ phổ biến dành cho máy tính. Để xem ascent, descentline-gap: mở hộp thoại Font Info, chọn trình đơn OS/2 rồi chọn thẻ Metrics. Để xem UPM: mở hộp thoại Font Info, sau đó chọn trình đơn General.

Tìm hiểu về bảng phông chữ

Bạn có thể nhận thấy rằng các khái niệm như "tăng dần" được nhiều chỉ số tham chiếu đến, ví dụ: có chỉ số hheaAscent, typoAscentwinAscent. Đây là kết quả của việc nhiều hệ điều hành áp dụng các phương pháp khác nhau để hiển thị phông chữ: các chương trình trên thiết bị OSX thường sử dụng chỉ số phông chữ hhea* — trong khi các chương trình trên thiết bị Windows thường sử dụng chỉ số phông chữ typo* (còn được gọi là sTypo*) hoặc win*.

Tuỳ thuộc vào phông chữ, trình duyệt và hệ điều hành, phông chữ sẽ được hiển thị bằng cách sử dụng các chỉ số hhea, typo hoặc win.

Mac Windows
Chromium Sử dụng chỉ số từ bảng "hhea". Sử dụng chỉ số từ bảng "lỗi chính tả" nếu bạn đã đặt "USE_TYPO_METRICS", nếu không, hãy sử dụng chỉ số từ bảng "giành chiến thắng".
Firefox Sử dụng chỉ số từ bảng "lỗi chính tả" nếu bạn đã đặt "USE_TYPO_METRICS", nếu không, hãy sử dụng chỉ số từ bảng "hhea". Sử dụng chỉ số từ bảng "lỗi chính tả" nếu bạn đã đặt "USE_TYPO_METRICS", nếu không, hãy sử dụng chỉ số từ bảng "giành chiến thắng".
Safari Sử dụng chỉ số từ bảng "hhea". Sử dụng chỉ số từ bảng "lỗi chính tả" nếu bạn đã đặt "USE_TYPO_METRICS", nếu không, hãy sử dụng chỉ số từ bảng "giành chiến thắng".

Để biết thêm thông tin về cách hoạt động của các chỉ số về phông chữ trên các hệ điều hành, hãy xem bài viết này về chỉ số ngành dọc.

Khả năng tương thích trên nhiều thiết bị

Đối với phần lớn phông chữ (ví dụ: ~90% phông chữ do Google Fonts lưu trữ) có thể sử dụng an toàn các chỉ số phông chữ mà không cần biết hệ điều hành của người dùng: nói cách khác, đối với những phông chữ này, giá trị của ascent-override, descent-overridelinegap-override vẫn giữ nguyên bất kể các chỉ số hhea, typo hay win có áp dụng hay không. Kho lưu trữ này cung cấp thông tin về những phông chữ mà chế độ này áp dụng và không áp dụng.

Nếu bạn đang sử dụng phông chữ yêu cầu sử dụng các bộ ghi đè chỉ số phông chữ riêng biệt cho thiết bị OSX và Windows, thì bạn nên sử dụng ghi đè chỉ số phông chữ và size-adjust chỉ được khuyên dùng nếu bạn có khả năng thay đổi biểu định kiểu dựa trên hệ điều hành của người dùng.

Sử dụng chế độ ghi đè chỉ số phông chữ

Vì chế độ ghi đè chỉ số phông chữ được tính toán bằng cách sử dụng thông tin đo lường lấy từ siêu dữ liệu của phông chữ trên web (không phải phông chữ dự phòng), nên các chế độ này vẫn giữ nguyên bất kể phông chữ nào được dùng làm phông chữ dự phòng. Ví dụ:

body {
  font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}

@font-face {
  font-family: "fallback for Poppins";
  src: local("Arial");
  ascent-override: 105%;
  descent-override: 35%;
  line-gap-override: 10%;
}

@font-face {
  font-family: "another fallback for Poppins";
  src: local("Roboto");
  ascent-override: 105%;
  descent-override: 35%;
  line-gap-override: 10%;
}

Cách hoạt động của tính năng điều chỉnh kích thước

Giới thiệu

Bộ mô tả CSS size-adjust điều chỉnh tỷ lệ chiều rộng và chiều cao của phông chữ theo tỷ lệ tương ứng. Ví dụ: size-adjust: 200% điều chỉnh tỷ lệ ký tự phông chữ thành gấp đôi kích thước ban đầu; size-adjust: 50% điều chỉnh tỷ lệ ký tự phông chữ thành một nửa kích thước ban đầu.

Sơ đồ cho thấy kết quả của việc sử dụng "size- ngủ" (điều chỉnh kích thước: 50%) và "size-adjust" (điều chỉnh kích thước: 200%).

Bản thân size-adjust có một số ứng dụng hạn chế để cải thiện phông chữ dự phòng: trong hầu hết các trường hợp, phông chữ dự phòng cần được thu hẹp hoặc mở rộng một chút (thay vì theo tỷ lệ) để phù hợp với phông chữ trên web. Tuy nhiên, việc kết hợp size-adjust với chế độ ghi đè chỉ số phông chữ sẽ giúp 2 phông chữ bất kỳ khớp với nhau cả chiều ngang và chiều dọc.

Đây là cách size-adjust được sử dụng trong biểu định kiểu:

@font-face {
  font-family: "fallback for poppins";
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

Do cách tính size-adjust (được giải thích trong phần tiếp theo), giá trị của size-adjust (và các chế độ ghi đè chỉ số phông chữ tương ứng) sẽ thay đổi tuỳ thuộc vào phông chữ dự phòng được sử dụng:

body {
  font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}

@font-face {
  font-family: poppins-fallback;
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

@font-face {
  font-family: poppins-fallback-android;
  src: local("Roboto");
  size-adjust: 55.5193474%:
  ascent-override: 180.1173909%;
  descent-override: 63.04108683%;
  line-gap-override: 18.01173909%;
}

Tính toán ghi đè chỉ số phông chữ và điều chỉnh kích thước

Dưới đây là các phương trình để tính size-adjust và ghi đè chỉ số phông chữ:

size-adjust = avgCharacterWidth of web font / avgCharacterWidth of fallback font
ascent-override = web font ascent / (web font UPM * size-adjust)
descent-override = web font descent / (web font UPM * size-adjust)
line-gap-override = web font line-gap / (web font UPM * size-adjust)

Hầu hết các dữ liệu đầu vào này (tức là chiều lên, chiều xuống và khoảng cách dòng) có thể được đọc trực tiếp từ siêu dữ liệu của phông chữ web. Tuy nhiên, avgCharacterWidth cần phải là giá trị gần đúng.

Ước tính chiều rộng ký tự trung bình

Nói chung, chiều rộng ký tự trung bình chỉ có thể gần đúng, nhưng có một số trường hợp có thể tính chính xác chiều rộng này: chẳng hạn như khi sử dụng phông chữ đơn điệu hoặc khi biết trước nội dung của chuỗi văn bản.

Một ví dụ về phương pháp đơn thuần để tính avgCharacterWidth là lấy chiều rộng trung bình của tất cả [a-z\s] ký tự.

 Biểu đồ so sánh chiều rộng của từng ký tự Roboto [a-zs].
Chiều rộng của phông chữ Roboto glyph

Tuy nhiên, việc trọng số tất cả các ký tự như nhau có thể sẽ làm thiếu chiều rộng của các chữ cái thường dùng (ví dụ: e) và thừa trọng số chiều rộng của các chữ cái ít dùng (ví dụ: z).

Một phương pháp phức tạp hơn giúp cải thiện độ chính xác là xem xét tần suất chữ cái và thay vào đó tính toán chiều rộng trung bình có trọng số tần suất của [a-z\s] ký tự. Bài viết này là tài liệu tham khảo tốt cho tần suất chữ cái và độ dài từ trung bình của các văn bản tiếng Anh.

Biểu đồ hiển thị tần suất chữ cái cho tiếng Anh.
Tần suất dùng chữ cái trong tiếng Anh

Chọn phương pháp

Hai phương pháp được thảo luận trong bài viết này, mỗi phương pháp đều có ưu và nhược điểm riêng:

  • Việc sử dụng chế độ ghi đè chỉ số phông chữ là một phương pháp hiệu quả nếu bạn bắt đầu tối ưu hoá tính năng dự phòng phông chữ. Mặc dù đây là phương pháp đơn giản hơn trong hai phương pháp, nhưng cách này thường đủ mạnh để giảm đáng kể mức độ thay đổi bố cục liên quan đến phông chữ.

  • Mặt khác, nếu bạn muốn độ chính xác cao hơn và sẵn sàng làm nhiều việc cũng như kiểm thử hơn, thì việc kết hợp size-adjust là một phương pháp hữu ích. Khi được triển khai đúng cách, phương pháp này có thể loại bỏ hiệu quả việc thay đổi bố cục liên quan đến phông chữ.

Chọn phông chữ dự phòng

Các kỹ thuật được mô tả trong bài viết này dựa vào việc sử dụng chế độ ghi đè chỉ số phông chữ và size-adjust để chuyển đổi các phông chữ có sẵn trên máy, thay vì cố gắng tìm một phông chữ trên máy gần giống với phông chữ trên web. Khi chọn phông chữ trên máy, điều quan trọng là phải nhớ rằng rất ít phông chữ được cung cấp rộng rãi trên thị trường và sẽ không có phông chữ nào tồn tại trên mọi thiết bị.

Arial là phông chữ dự phòng được đề xuất cho phông chữ alt-serif và Times New Roman là phông chữ dự phòng nên dùng cho phông chữ serif. Tuy nhiên, cả hai phông chữ này đều không có trên Android (Roboto là phông chữ hệ thống duy nhất trên Android).

Ví dụ bên dưới sử dụng 3 phông chữ dự phòng để đảm bảo phạm vi sử dụng rộng rãi cho thiết bị: phông chữ dự phòng nhắm đến thiết bị Windows/Mac, phông chữ dự phòng nhắm đến các thiết bị Android và phông chữ dự phòng sử dụng bộ phông chữ chung.

body {
  font-family: "Poppins", poppins-fallback, poppins-fallback-android, sans-serif;
}

/*
Poppins font metrics:
- ascent = 1050
- descent = 350
- line-gap = 100
- UPM: 1000
AvgCharWidth:
- Poppins: 538.0103768
- Arial: 884.1438804
- Roboto: 969.0502537
*/

@font-face {
  font-family: poppins-fallback;
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

@font-face {
  font-family: poppins-fallback-android;
  src: local("Roboto");
  size-adjust: 55.5193474%:
  ascent-override: 180.1173909%;
  descent-override: 63.04108683%;
  line-gap-override: 18.01173909%;
}

Yêu cầu phản hồi

Vui lòng liên hệ nếu bạn có ý kiến phản hồi về trải nghiệm sử dụng chế độ ghi đè chỉ số phông chữ và size-adjust.