Bỏ qua, sang nội dung chính
← Về danh sách

· Working ·

Font tiếng Việt cho UI: cách kiểm dấu trong 5 phút

Chọn font cho giao diện tiếng Việt bắt đầu từ ba phép kiểm: subset vietnamese trên Google Fonts, dấu thanh chồng dấu mũ ở cỡ 12–14px, và line-height đủ chỗ cho chữ hoa có dấu. Kèm bảng mười font phổ biến, chỉ ghi điều đã xác minh.

Một font dùng được cho UI tiếng Việt phải qua ba phép kiểm: có subset vietnamese trên Google Fonts (hoặc đủ glyph nếu tự host), dấu thanh chồng lên dấu mũ vẫn tách bạch ở cỡ 12–14px, và chữ hoa có dấu không đụng dòng trên ở line-height bạn dùng. Cả ba kiểm được trong khoảng năm phút.

Tôi là Hai Le, designer làm design system và tự dựng site này bằng code. Bài này là bản viết lại. Bản cũ khẳng định Inter thua Be Vietnam Pro ở phần dấu, nhưng tôi không có phép đo nào cho câu đó, nên tôi bỏ nó và thay bằng cách kiểm mà bạn tự làm được.

Vì sao "hỗ trợ tiếng Việt" chưa đủ để chọn font?

"Hỗ trợ tiếng Việt" thường chỉ có nghĩa là font có đủ ký tự Unicode. Cách các dấu được vẽ và đặt thì là chuyện khác, và tiếng Việt khó hơn phần lớn ngôn ngữ dùng chữ Latin vì một chữ có thể mang hai dấu cùng lúc: dấu mũ hoặc dấu trăng cộng thêm dấu thanh, như ề, ẫ, ặ.

Hướng dẫn làm font của Google Fonts (GF Guide) có hẳn một trang về dấu. Trang đó gọi trường hợp này là dấu chồng (stacked diacritics) và nêu ba điều đáng nhớ: khoảng cách giữa hai dấu thường hẹp và phải nhất quán trong cả bộ chữ, dấu chồng có thể vẽ nhỏ hơn dấu đứng riêng để giữ cân bằng (nhất là trên chữ hoa), và dấu không được quá cao hoặc quá đậm. Khi nhà làm font bỏ qua những điều này, bạn sẽ thấy dấu hỏi dính vào dấu mũ ở cỡ chữ nhỏ, hoặc chữ hoa có dấu cao vượt hẳn các chữ còn lại trong dòng.

Be Vietnam Pro là ví dụ của hướng ngược lại. README của dự án trên GitHub viết rằng nhóm tác giả đã chỉnh lại các chữ tiếng Việt với "dạng dấu thích ứng cho từng trường hợp sử dụng". Google Fonts ghi tác giả là Lâm Bảo, Tony Le và ViệtAnh Nguyễn.

Font nào hỗ trợ tiếng Việt tốt cho UI?

Bảng dưới chỉ ghi điều tôi kiểm được từ dữ liệu metadata của Google Fonts ngày 2026-10-04: font có subset vietnamese hay không, ai làm, và có những trục biến thiên nào. Tôi không xếp hạng chất lượng dấu, vì việc đó cần bạn tự nhìn bằng chuỗi thử ở phần sau.

FontSubset vietnameseTác giả theo Google FontsTrục biến thiên
Google Sans FlexCóGooglewght 1–1000, wdth, opsz, slnt, GRAD, ROND
Be Vietnam ProCóLâm Bảo, Tony Le, ViệtAnh NguyễnKhông (font tĩnh, 18 kiểu)
InterCóRasmus Anderssonwght 100–900, opsz 14–32
RobotoCóChristian Robertson và cộng sựwght 100–900, wdth 75–100
Noto SansCóGooglewght 100–900, wdth 62.5–100
Nunito SansCóVernon Adams và cộng sựwght 200–1000, wdth, opsz, YTLC
MontserratCóJulieta Ulanovsky và cộng sựwght 100–900
LexendCóBonnie Shaver-Troup và cộng sựwght 100–900
PoppinsKhôngIndian Type Foundry và cộng sựKhông (font tĩnh)
DM SansKhôngColophon Foundrywght 100–1000, opsz 9–40

Hai dòng cuối đáng để ý vì cả hai rất phổ biến trong file Figma mẫu. Bản Poppins trên Google Fonts có subset latin-ext, nhưng dải ký tự của subset này bỏ qua đoạn U+1EA0 đến U+1EF1. Đó là nơi chứa phần lớn chữ tiếng Việt có dấu thanh: ạ, ề, ộ, ữ. Còn ă, đ, ơ, ư nằm trong đoạn U+0100 đến U+02BA nên vẫn có. Kết quả là chữ "Đề" sẽ có chữ Đ bằng Poppins và chữ ề bằng font dự phòng của hệ điều hành. Trong Figma bạn có thể không thấy lỗi này, vì Figma dùng file font cài trên máy, còn trình duyệt chỉ có những gì Google Fonts gửi xuống.

Kiểm dấu tiếng Việt của một font trong 5 phút thế nào?

Bạn cần một trang HTML trống hoặc một frame trong Figma, cộng thêm trình duyệt.

  1. Kiểm subset. Trên trang font của Google Fonts, xem danh sách ngôn ngữ có Vietnamese không. Nếu muốn chắc hơn, mở API CSS của font và tìm dòng chú thích /* vietnamese */. Không có khối đó thì trình duyệt sẽ lấy chữ có dấu từ font khác.

    curl -s -A "Mozilla/5.0" "https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro" | grep "vietnamese"
  2. Gõ chuỗi thử dấu chồng. Dùng chuỗi có đủ dấu mũ, dấu trăng và dấu móc cộng năm dấu thanh: ấ ầ ẩ ẫ ậ · ắ ằ ẳ ẵ ặ · ế ề ể ễ ệ · ố ồ ổ ỗ ộ · ớ ờ ở ỡ ợ · ứ ừ ử ữ ự. Xem ở 12px và 14px, weight bạn thật sự dùng. Câu hỏi duy nhất: phân biệt được dấu hỏi với dấu ngã không, và dấu thanh có chạm dấu mũ không.

  3. Thử chữ hoa ở cỡ tiêu đề. Gõ ỄỘ ẲẪ ỞỮ ở cỡ tiêu đề lớn nhất. Dấu chồng trên chữ hoa là chỗ dễ lộ nhất, vì chữ hoa đã cao sẵn.

  4. Kiểm line-height. Xếp hai dòng: dòng trên có chữ có nét xuống như gy, dòng dưới là chữ hoa có dấu chồng như ỄỘ. Đặt đúng line-height của style tiêu đề và xem hai dòng có chạm nhau không.

  5. Kiểm font dự phòng. Trong Chrome DevTools, chọn đoạn chữ, mở tab Computed và kéo xuống mục Rendered Fonts. Nếu một đoạn chữ tiếng Việt liệt kê hai font, nghĩa là một phần ký tự đang rơi về font hệ thống.

Mỗi bước mất khoảng một phút. Bước 5 bắt được lỗi kiểu Poppins ở trên mà mắt thường dễ bỏ qua khi font dự phòng trông na ná.

Line-height bao nhiêu thì đủ chỗ cho dấu tiếng Việt?

Tôi không đưa ra con số chung được, vì mỗi font đặt dấu ở độ cao khác nhau. Điều tôi có thể chỉ ra là chỗ cần kiểm.

Chữ thân bài ít khi gặp vấn đề. Ở site này, chữ nội dung là 16px với line-height 1.4, tức 22.4px, đủ thoáng cho dấu chồng. Rủi ro nằm ở tiêu đề lớn, nơi designer hay siết line-height để khối chữ gọn. Style tiêu đề 48px của site đang dùng line-height 1.04. Ở mức đó, một tiêu đề hai dòng có chữ hoa mang dấu chồng là trường hợp phải kiểm bằng bước 4 ở trên trước khi chốt.

Tracking cũng ảnh hưởng. Hệ thống ở đây dùng tracking âm tăng dần theo cỡ: -0.04em từ 32px trở lên, -0.025em cho 18–28px, -0.01em cho 14px, và 0 cho chữ thân 16px. Tracking âm kéo các chữ sát nhau theo chiều ngang, nên dấu của hai chữ cạnh nhau cũng gần nhau hơn. Khi thử, hãy bật đúng tracking bạn định dùng.

Vì sao site này đổi từ Be Vietnam Pro sang Google Sans Flex?

Tháng 9/2026, tôi đổi font chính của site từ Be Vietnam Pro sang Google Sans Flex. Google Sans Flex được thêm vào Google Fonts ngày 12/11/2025 và có subset vietnamese. Lý do ghi trong DESIGN.md của site gồm hai ý: dấu tiếng Việt được vẽ cho chính họ chữ này, và dáng chữ grotesque gọn, ít tương phản nét hợp với bố cục hiện tại.

Google Sans Flex là font biến thiên với sáu trục. Site chỉ nạp trục wght và chỉ dùng hai mức 400 và 500. Các trục còn lại (độ rộng, cỡ quang học, độ nghiêng, độ tròn, grade) bị bỏ có chủ đích để file nhẹ hơn. Với Next.js, phần nạp font trông như sau:

const googleSansFlex = Google_Sans_Flex({
  subsets: ["latin", "latin-ext", "vietnamese"],
  // ...
});

Trong mảng subsets, vietnamese là mục tôi coi là bắt buộc. Thiếu nó, ký tự tiếng Việt vẫn hiện, nhưng bằng font khác, và lỗi này thường chỉ lộ ra trên máy người dùng.

Quyết định đổi font phải được ghi ở ba nơi cùng lúc: CSS, file DESIGN.md, và file quy ước cho AI. Nếu chỉ sửa CSS, lần sau tôi nhờ AI dựng giao diện, nó sẽ đọc tài liệu cũ và quay lại font cũ. Cách tôi tổ chức các file đó nằm ở bài DESIGN.md là gì. Nếu bạn muốn đưa font và cỡ chữ thành biến dùng chung giữa Figma và code, đọc bài Design token là gì.

Nên ghi gì về font vào design system?

Một mục chữ trong design system nên trả lời được những câu mà người mới vào team (hoặc AI) sẽ hỏi:

  • Font nào, subset nào bắt buộc, nạp những weight nào.
  • Thang cỡ chữ, line-height và tracking cho từng bậc.
  • Những ngoại lệ có tên. Ở site này, nhãn Button là chỗ duy nhất dùng weight 600.
  • Chuỗi thử tiếng Việt dùng để duyệt khi đổi font.

Mục cuối thường bị quên. Ở dự án Joyme, hệ thống chữ dùng một họ Nunito Sans với ba độ đậm và sáu cỡ từ 12 đến 32px, bạn có thể xem bảng chữ đó trong case study Joyme. Nunito Sans có subset vietnamese trên Google Fonts, nhưng điều đó chỉ nói về ký tự. Chất lượng dấu vẫn phải kiểm bằng mắt, theo đúng năm bước ở trên.

Khi chữ đã ổn, bước tiếp theo thường là nhịp khoảng trắng quanh chữ, phần tôi viết trong bài Lưới 4px và nhịp khoảng trắng. Nếu bạn đang dùng AI để dựng giao diện từ Figma, bài Claude Code cho designer kể cách tôi giữ những quy tắc như subset bắt buộc khỏi bị AI bỏ qua.

Nếu team bạn cần người dựng design system cho sản phẩm tiếng Việt, xem thêm về tôi ở trang giới thiệu.

Nguồn

  • Google Fonts metadata: subset, tác giả, trục biến thiên, ngày thêm của từng font. Truy cập 2026-10-04.
  • Google Fonts CSS API: dải unicode-range của subset latin-ext và vietnamese. Truy cập 2026-10-04.
  • GF Guide: Diacritics: dấu chồng trong tiếng Việt, khoảng cách và kích thước dấu. Truy cập 2026-10-04.
  • Be Vietnam Pro trên GitHub: mục đích thiết kế, giấy phép OFL 1.1. Truy cập 2026-10-04.
  • DESIGN.md, app/globals.css và app/[locale]/layout.tsx trong repo của site này.

Câu hỏi thường gặp

Font có subset vietnamese trên Google Fonts là đủ dùng cho UI chưa?
Subset vietnamese chỉ xác nhận font có đủ ký tự. Nó không cho biết dấu được vẽ đẹp hay chen chúc ở cỡ nhỏ. Bạn vẫn cần gõ chuỗi thử có ề, ữ, ộ, ẳ và xem ở 12px, 14px và cỡ tiêu đề lớn nhất.
Vì sao Poppins hiển thị chữ ề bằng một font khác?
Bản Poppins trên Google Fonts không có subset vietnamese. Dải latin-ext của nó bỏ qua vùng U+1EA0 đến U+1EF1, nơi chứa các chữ như ề, ộ, ữ, nên trình duyệt lấy những ký tự đó từ font dự phòng. Các chữ ă, đ, ơ, ư vẫn nằm trong latin-ext nên vẫn hiện bằng Poppins.
Line-height bao nhiêu thì đủ cho tiếng Việt?
Không có một con số chung, vì nó phụ thuộc chiều cao dấu của từng font. Cách kiểm nhanh là xếp hai dòng chữ hoa có dấu chồng, như ỄỘ trên dòng dưới và chữ có nét xuống như gy ở dòng trên, rồi xem hai dòng có chạm nhau ở line-height bạn định dùng không.
Site này dùng font gì?
Google Sans Flex, từ tháng 9/2026, thay cho Be Vietnam Pro. Site nạp subset vietnamese như điều kiện bắt buộc và chỉ dùng trục độ đậm, ở hai mức 400 và 500.