Catalina mang đến một phông chữ hệ thống có thể thay đổi mới và thống nhất cho macOS.
Mục "system-ui" của quy cách Mô-đun phông chữ CSS cấp 4 xác định một từ khoá phông chữ system-ui
cho phép nhà phát triển sử dụng phông chữ mặc định của hệ điều hành được tích hợp sẵn, tối ưu hoá turbo, bản địa hoá, chất lượng siêu cao, không cần tải xuống ngay trong trang web và ứng dụng của họ.
body {
font-family: system-ui;
}
Lựa chọn kiểu chữ này tương tự như việc nói "sử dụng phông chữ hệ thống mặc định cho ngôn ngữ hiện tại của người dùng này".
Trên macOS, phông chữ system-ui
là San Francisco, một phông chữ mà nhóm thiết kế đã kiểm tra, thử nghiệm và… gần đây đã nâng cấp! Trước tiên, chúng ta sẽ tìm hiểu về các tính năng mới thú vị của phông chữ có thể thay đổi trong Catalina, sau đó, chúng ta sẽ tìm hiểu về một số lỗi và cách các kỹ sư Chromium giải quyết những lỗi đó.
Bài đăng này giả định rằng bạn đã quen thuộc với phông chữ có thể thay đổi. Nếu không, hãy xem bài viết Giới thiệu về phông chữ có thể thay đổi trên web và video bên dưới.
Khả năng tương thích với trình duyệt
Tại thời điểm viết bài, system-ui
được Chromium (từ phiên bản 56), Edge (từ phiên bản 79), Safari (từ phiên bản 11) và Firefox (từ phiên bản 43) hỗ trợ nhưng phải có từ khoá -apple-system
. Hãy xem phần Tôi có thể sử dụng phông chữ có thể thay đổi không? để biết thông tin cập nhật.
Sức mạnh mới
Kể từ Chromium 83, các nhà phát triển web có thể sử dụng những khả năng mới mà Catalina mang lại cho phông chữ hệ thống. Phông chữ system-ui
hiện có nhiều chế độ cài đặt biến số hơn: kích thước quang học và 2 chế độ điều chỉnh độ đậm riêng biệt:
h1 { font-family: system-ui; font-weight: 700; font-variation-settings: 'wght' 750 ; }
h1 { font-family: system-ui; font-weight: 700; font-variation-settings: 'wght' 750, 'opsz' 20, 'GRAD' 400, 'YAXS' 400 ; }
Trên Mojave, system-ui
là một phông chữ có thể thay đổi và chỉ có chế độ cài đặt wght
. Trong khi system-ui
trên Catalina là một phông chữ biến đổi với các chế độ cài đặt wght
, opsz
, GRAD
và YAXS
.
Có vẻ như tôi có một số cơ hội thiết kế nâng cao tăng dần! Bạn có thể tìm hiểu kỹ hơn về các điểm tinh tế của phông chữ hệ thống nếu muốn.
wght
Chấp nhận độ đậm phông chữ từ 0
đến 900
và được áp dụng cho tất cả các ký tự.
/* 0-900 */
font-variation-settings: 'wght' 750;
opsz
Định cỡ bằng mắt tương tự như kerning hoặc khoảng cách giữa các chữ cái, nhưng khoảng cách được thực hiện bằng mắt người thay vì bằng toán học. Giá trị 19
trở xuống dành cho khoảng cách giữa văn bản và nội dung, trong khi 20
trở lên dành cho khoảng cách giữa tiêu đề và tên hiển thị.
/* 19 or 20 */
font-variation-settings: 'opsz' 20;
GRAD
Tương tự như trọng số, nhưng không ảnh hưởng đến khoảng cách ngang. Trường này chấp nhận các giá trị từ 400
đến 1000
.
/* 400-1000 */
font-variation-settings: 'GRAD' 500;
YAXS
Kéo dài glyph theo chiều dọc. Trường này chấp nhận các giá trị từ 400
đến 1000
.
/* 400-1000 */
font-variation-settings: 'YAXS' 500;
Kết hợp các lựa chọn
Với một vài dòng CSS, chúng ta có thể điều chỉnh chế độ cài đặt phông chữ thành một kiểu chữ in đậm mà chúng ta chọn hoặc thử các tổ hợp thú vị khác:
font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;
Và thế là người dùng Chromium trên macOS sẽ thấy phiên bản tuỳ chỉnh được nâng cấp với trọng số 750 cùng một số điểm điều chỉnh thú vị khác 👍
macOS 10.15 đã thêm các tính năng mới vào phông chữ hệ thống và trong macOS 10.15, một lỗi system-ui
phức tạp đã được ghi lại trong trình theo dõi lỗi của Chromium. Tôi tự hỏi liệu chúng có liên quan đến nhau không!?
Phụ lục: Phép hồi quy system-ui
Câu chuyện này bắt đầu bằng một lỗi khác: #1005969. Vấn đề này được báo cáo trên macOS 10.15 vì khoảng cách phông chữ system-ui
trông hẹp và chật chội.

Thông tin khái quát
Bạn có bao giờ nhận thấy trên macOS 10.14, các đoạn văn hoặc tiêu đề của bạn "chụp" vào một phông chữ có giao diện khác khi kích thước tăng hoặc giảm không?
Trên Mojave (macOS 10.14), phông chữ system-ui
chuyển đổi giữa hai phông chữ tuỳ thuộc vào cỡ chữ mục tiêu. Khi văn bản nằm trong 20px
, macOS sẽ dùng phông chữ "San Francisco Text". Khi văn bản có kích thước 20px
trở lên, macOS sẽ dùng "San Francisco Display". Tính năng định cỡ quang học được tích hợp tĩnh vào 2 phông chữ riêng biệt.
Catalina (macOS 10.15) đã phát hành một phông chữ đa dạng mới, hợp nhất cho San Francisco. Không cần quản lý "Văn bản" và "Hiển thị" nữa. Nó cũng có chế độ cài đặt biến thể mới opsz
như mô tả ở trên.
h1 {
font-variation-settings: 'opsz' 20;
}
Rất tiếc, giá trị opsz
mặc định trong phông chữ Catalina mới là 20
và các kỹ sư Chromium chưa chuẩn bị sẵn sàng để áp dụng opsz
cho phông chữ hệ thống. Điều này dẫn đến việc các kích thước nhỏ hơn hiển thị quá hẹp.
Để khắc phục vấn đề đó, Chromium cần áp dụng opsz
một cách chính xác cho phông chữ hệ thống. Điều này dẫn đến việc Vấn đề #1005969 được khắc phục. Chiến thắng! Hay là…?
Chưa xong
Đây là lúc mọi chuyện trở nên phức tạp: Chromium đã áp dụng opsz
nhưng vẫn có gì đó không ổn. Phông chữ hệ thống trên máy Mac có thêm một bảng phông chữ được gọi là trak
, giúp điều chỉnh khoảng cách theo chiều ngang. Trong khi khắc phục, các kỹ sư Chromium nhận thấy rằng trên macOS, khi truy xuất các chỉ số ngang từ một đối tượng CTFontRef
, các chỉ số trak
đã được đưa vào kết quả chỉ số. Thư viện tạo hình HarfBuzz
của Chromium cần các chỉ số mà giá trị trak
chưa được tính đến.

Về nội bộ, Skia (thư viện đồ hoạ, không phải kiểu chữ có cùng tên) sử dụng cả lớp CGFontRef
từ CoreGraphics
và lớp CTFontRef
từ CoreText
. Do các lượt chuyển đổi nội bộ bắt buộc giữa những đối tượng đó (được dùng để duy trì khả năng tương thích ngược và truy cập vào các API cần thiết trên cả hai lớp), Skia sẽ mất thông tin về trọng lượng trong một số trường hợp và các phông chữ in đậm sẽ ngừng hoạt động. Vấn đề này đã được theo dõi trong Vấn đề #1057654.
Skia vẫn cần hỗ trợ macOS 10.11 vì Chromium vẫn hỗ trợ hệ điều hành này. Trên phiên bản 10.11, phông chữ "San Francisco Text" và "San Francisco Display" thậm chí còn không phải là phông chữ có thể thay đổi. Thay vào đó, mỗi kiểu chữ là một nhóm gồm các phông chữ riêng biệt cho mọi độ đậm có sẵn. Đến một thời điểm nào đó, mã nhận dạng glyph của chúng không còn đồng bộ với nhau. Vì vậy, nếu Skia định hình văn bản (chuyển đổi văn bản thành các glyph có thể vẽ) bằng "San Francisco Text", thì văn bản đó sẽ trở nên vô nghĩa nếu được vẽ bằng "San Francisco Display" và ngược lại. Ngay cả khi Skia chỉ yêu cầu một kích thước khác, macOS có thể chuyển sang kích thước khác. Bạn có thể luôn sử dụng một trong các phông chữ và chỉ cần điều chỉnh tỷ lệ (sử dụng ma trận để tăng tỷ lệ thay vì yêu cầu kích thước lớn hơn) nhưng CoreText
có một vấn đề là nó sẽ không tăng tỷ lệ các glyph sbix (biểu tượng cảm xúc có màu) (chỉ giảm tỷ lệ). Quy trình này phức tạp hơn một chút. CoreText
dường như giới hạn phạm vi theo chiều dọc sau khi áp dụng ma trận. Điều này có vẻ như liên quan đến việc không thể vẽ biểu tượng cảm xúc ở góc 45 độ. Trong mọi trường hợp, nếu muốn biểu tượng cảm xúc của mình xuất hiện ở kích thước lớn, bạn cần sao chép phông chữ để có được phiên bản lớn.
Vì vậy, để tạo bản sao của các đối tượng CTFont
ở nhiều kích thước khác nhau trong nội bộ trong khi vẫn đảm bảo sử dụng cùng một dữ liệu phông chữ cơ bản, Chromium đã kéo CGFont
ra khỏi CTFont
, sau đó tạo một CTFont
mới từ CGFont
(các đối tượng CGFont
không phụ thuộc vào kích thước, quá trình chuyển đổi kỳ diệu diễn ra ở cấp CoreText
). Điều này vẫn ổn cho đến phiên bản 10.154. Trong 10.15, chuyến đi khứ hồi này đã làm mất quá nhiều thông tin, dẫn đến vấn đề về trọng lượng. Flutter nhận thấy vấn đề về trọng lượng và đã đưa ra một giải pháp thay thế để đổi kích thước nhằm tạo CTFont
mới trực tiếp từ CTFont
ban đầu trong khi kiểm soát kích thước quang học trực tiếp bằng cách sử dụng một thuộc tính cũ nhưng không được ghi lại trong CoreText
. Điều này giúp mọi thứ hoạt động trên phiên bản 10.11 và khắc phục các vấn đề khác (chẳng hạn như đặt kích thước quang học thành giá trị mặc định một cách rõ ràng).
Tuy nhiên, cách này sẽ giữ lại nhiều "phép màu" CoreText
hơn trong phông chữ. Một trong những lý do có vẻ là do Chrome vẫn điều chỉnh khoảng cách giữa các glyph theo cách nào đó ngoài bảng trak
(Chromium đã cố gắng ngăn chặn việc áp dụng bảng này thông qua một thuộc tính khác chưa được ghi lại).
CGFont
không thực hiện bất kỳ "phép màu" nào trong số này, vì vậy có thể Chromium sẽ loại bỏ CGFont
khỏi CTFont
và chỉ dùng nó để nhận các tính năng nâng cao? Rất tiếc, cách này sẽ không hiệu quả vì CoreText
cũng có thể gây ra các vấn đề khác về phông chữ. Ví dụ: tính năng này sẽ làm cho biểu tượng cảm xúc nhỏ lớn hơn một chút so với kích thước bạn yêu cầu (tăng kích thước của biểu tượng cảm xúc lên một chút). CGFont
không biết về điều này, vì vậy, biểu tượng cảm xúc dựa trên sbix của bạn sẽ quá gần nhau vì bạn sẽ đo ở một kích thước nhưng CoreText
sẽ vẽ chúng lớn hơn một chút. Chromium muốn có những tiến bộ CTFont
, nhưng không muốn bị theo dõi và tốt nhất là không muốn có bất kỳ sự can thiệp nào khác.
Vì bản sửa lỗi cho vấn đề về khoảng cách yêu cầu một bộ các bản sửa lỗi Blink và Skia được kết nối với nhau, nên các kỹ sư Chromium không thể "chỉ cần quay lại" để khắc phục vấn đề. Các kỹ sư Chromium cũng đã thử sử dụng một cờ bản dựng khác để thay đổi đường dẫn mã liên quan đến phông chữ trong Skia. Cách này đã khắc phục được vấn đề về phông chữ in đậm, nhưng lại gây ra vấn đề về khoảng cách.
Cách khắc phục
Cuối cùng, tất nhiên Chromium muốn khắc phục cả hai vấn đề này. Giờ đây, Chromium sẽ sử dụng các hàm chỉ số phông chữ OpenType tích hợp sẵn của HarfBuzz để truy xuất chỉ số ngang trực tiếp từ dữ liệu nhị phân trong bảng phông chữ của phông chữ hệ thống. Bằng cách này, Chromium sẽ bỏ qua CoreText
và Skia khi phông chữ có bảng trak
(trừ khi đó là phông chữ biểu tượng cảm xúc).

Trong thời gian chờ đợi, vẫn còn Vấn đề về Skia #10123 cần theo dõi để khắc phục hoàn toàn vấn đề này trong Skia, đồng thời quay lại sử dụng Skia để truy xuất các chỉ số phông chữ hệ thống từ đó, thay vì bản sửa lỗi hiện tại thông qua HarfBuzz
.