Typography chiếm 90% nội dung mọi UI — chữ khó đọc thì mọi element khác đẹp đến đâu cũng vô ích. Bài này hướng dẫn xây type system end-to-end: chọn font + pair, build modular scale 8 step, set line-height và measure đúng device, optimize woff2 + font-display swap để pass Core Web Vitals 2026.
Vì sao type system quyết định readability và performance
Type system là một trong 6 thành phần UI cốt lõi nhưng thường bị underspec trong đơn vị outsource. Designer set font-size hardcode 18px, line-height 1,4 và “thấy đẹp là chốt” — kết quả là user mobile zoom in không scale được, fail accessibility hoặc đọc 2 paragraph rồi bỏ.
Web typography 2026 ổn định quanh 4 quyết định: modular scale ratio 1.25 hoặc 1.333, line-height 1,5-1,7 cho body, measure 50-75 ký tự mỗi dòng, font self-host woff2 + font-display swap. Variable font đã chính thức trở thành mặc định 2026 — giảm file size so với load 4-6 weight riêng.
Tác động tới Core Web Vitals 2026
Web font ảnh hưởng trực tiếp LCP và CLS — 2 chỉ số quan trọng nhất của Core Web Vitals. Cấu hình sai làm LCP từ 2s lên 4s, CLS từ 0,05 lên 0,3 (Google flag “Poor” toàn page).
Pass CWV không chỉ là chuyện SEO — Google đã chính thức dùng CWV làm xếp hạng signal từ 2021 và mở rộng INP từ 2024. Site fail CWV thua trực tiếp đối thủ pass CWV trong cùng SERP query.
Anatomy chữ và đơn vị web 2026
Trước khi vào scale, designer cần hiểu 4 thuộc tính chữ và 3 đơn vị dùng song song trong CSS. Sai đơn vị là lỗi typography phổ biến nhất ở dev junior — set body font 18px hardcode khiến user mobile zoom in không scale được, fail accessibility.
5 thuộc tính font cốt lõi
- font-family: hệ font (Inter, Roboto, Source Sans 3). Fallback chain cần system-ui ở cuối để tránh trắng trang khi font load fail.
- font-size: kích thước, dùng rem để scale theo user zoom. Body 1rem = 16px mặc định browser.
- font-weight: độ đậm 100-900. Variable font cho phép arbitrary value (vd 567), static font giới hạn step có sẵn.
- line-height: chiều cao dòng, dùng unitless number (1.5) thay vì px để inherit đúng theo cascade.
- letter-spacing: khoảng giữa chữ, dùng em (relative theo font-size) thay vì px. Heading lớn thường tracking âm (-0.01em đến -0.02em).
Đơn vị web — rem, em, px và clamp
- rem (relative em): tính theo root font-size mặc định 16px. Body text 1rem = 16px.
- Khi user zoom +20%, mọi rem scale theo. Đơn vị mặc định cho mọi font-size + spacing.
- em (relative em): tính theo parent. Hữu dụng cho component (button padding 0.5em scale theo font button).
- Hạn chế là nested em compound — em trong em trong em làm size thay đổi không lường.
- px (pixel cố định): chỉ dùng cho border, shadow blur, icon size. KHÔNG dùng cho font-size body vì fail user zoom.
- clamp(min, preferred, max): fluid type. Vd font-size: clamp(1rem, 0.5rem + 1vw, 1.25rem) để mobile 16px, desktop 20px, scale liên tục.
- Hữu dụng cho hero heading.
Quy tắc root: html { font-size: 100%; } (= 16px mặc định browser). KHÔNG set html { font-size: 62.5%; } để “1rem = 10px” — pattern cũ phá user zoom + accessibility.
Type scale modular — chọn ratio và sinh 8 step
Type scale là dãy size có quan hệ toán học, đảm bảo mỗi step rõ ràng khác step trước về thị giác.
Scale ngẫu nhiên (12, 13, 14, 16, 17, 19, 22) làm hierarchy mờ. Scale modular (12, 14, 16, 20, 25, 31, 39, 49 với ratio 1.25) tạo rhythm rõ ràng cho cả body và heading.
Designer 2026 dùng 1 trong 6 ratio phổ biến. Chọn ratio phụ thuộc loại sản phẩm — dashboard cần ratio nhỏ vì nhiều text dày, landing page cần ratio lớn cho CTA mạnh.
Ratio nhỏ 1.125 và 1.2 — dashboard nhiều text
- Ratio 1.125 (Major Second): bước nhỏ, scale 8 step gần nhau. Phù hợp dashboard SaaS có nhiều cấp text (caption / label / body / lead / sub-heading / heading 1-3).
- Ít contrast giữa step nên cần weight + color bổ sung cho hierarchy.
- Ratio 1.2 (Minor Third): mặc định Tailwind. Step vừa phải, scale 12, 14.4, 17.28, 20.74… hơi lệch số nguyên, designer thường round.
- Tốt cho 80% website.
- Ratio 1.25 (Major Third): Web22 dùng cho đa số project. Step rõ ràng, round thành 12, 14, 16, 20, 25, 31, 39, 49.
- 8 step đủ cho caption tới H1, không cần thêm.
Ratio lớn 1.333+ — landing page và editorial
- Ratio 1.333 (Perfect Fourth): step lớn hơn, hierarchy mạnh. Round thành 12, 16, 21, 28, 37, 50, 67, 89.
- Tốt cho landing page B2B / brand cao cấp cần CTA dày.
- Ratio 1.5 (Perfect Fifth): step rất lớn, dramatic. Phù hợp editorial / blog / danh mục dự án designer.
- Heading H1 to gấp 5 lần body, gây impact mạnh nhưng tốn whitespace.
- Ratio 1.618 (Golden Ratio): dùng được nhưng quá khắc nghiệt — H1 to gấp 6,8 lần body. Hiếm dùng production, hay xuất hiện trong showcase art.
Cách chọn nhanh: 1.125 cho dashboard nhiều text dày, 1.25 cho website business chuẩn, 1.333 cho landing page CTA mạnh, 1.5+ cho editorial / danh mục dự án. Tool typescale.com visualize 8 step với ratio bất kỳ và output CSS variable.
Line-height và measure — readability lâu dài
Line-height (chiều cao dòng) và measure (số ký tự / dòng) là 2 yếu tố quyết định readability — user đọc nhanh hay chậm, có hiểu nội dung không. Thiếu chú ý 2 yếu tố này khiến content chất lượng vẫn bị bỏ ngang ở dòng thứ 3.
Line-height body và heading
Line-height cho body text nên 1,5-1,7. Tailwind preset leading-relaxed (1.625) là lựa chọn phổ biến.
Quá thấp (1,2-1,3) làm dòng dính nhau khó đọc, quá cao (2,0+) làm khoảng cách rời rạc, mắt phải nhảy xa giữa dòng.
Body text 16-18px nên dùng line-height 1,6 (khoảng 25-29px chiều cao dòng). Heading lớn (32-49px) dùng line-height 1,1-1,15 vì mỗi dòng đã cao.
Heading nhỏ (20-25px) dùng line-height 1,25-1,3.
Measure 50-75 ký tự — optimal 60-65
- Measure body: 50-75 ký tự, optimal 60-65. Đo bằng max-width: 65ch trong CSS — đơn vị ch là chiều rộng số 0 của font hiện tại, ~9-10px cho hầu hết font sans.
- Dòng quá ngắn (dưới 40 ký tự): mắt phải nhảy dòng liên tục, mệt sau 5-10 paragraph. Phổ biến ở mobile khi designer set max-width quá nhỏ.
- Dòng quá dài (trên 90 ký tự): mắt khó tìm dòng kế tiếp khi xuống dòng. Phổ biến ở desktop khi quên set max-width — content fill 100% width 4K monitor.
Mobile typography và letter-spacing
Mobile base 16px, KHÔNG xuống 14px. Dưới 16px Safari iOS auto-zoom khi user focus input gây UX vỡ.
Heading mobile có thể giảm 1 step so với desktop (vd H1 desktop 49px xuống mobile 39px). Line-height mobile giữ 1,5-1,7 cho body.
Letter-spacing body 0 (default), heading -0,01em đến -0,02em (tighten cho heading dày + gọn hơn). Caps lock heading cần letter-spacing dương 0,05-0,1em vì cap glyph rộng đều, thiếu spacing dính nhau.
Web font — self-host vs Google Fonts CDN
2 lựa chọn deploy font: load từ Google Fonts CDN hoặc self-host (download woff2, để trên domain riêng). Mỗi cách có trade-off khác nhau về performance, privacy, độ ổn định.
Google Fonts CDN — pro và contra
- Pro: setup 1 link, cache phổ biến cho tới 2018 (sau Chrome 86 thì không còn share cross-domain nữa), update font version tự động không cần can thiệp.
- Contra DNS lookup: thêm 1 third-party DNS lookup + connection (50-150ms), latency biến động khi Google CDN chậm tại khu vực Đông Nam Á.
- Contra GDPR: vi phạm GDPR EU vì gửi IP user về Google không có consent. Đức năm 2022 đã có vụ phạt website €100 vì dùng Google Fonts CDN.
Self-host woff2 — pro và contra
- Pro privacy: không có third-party request, GDPR-compliant out-of-the-box. Quan trọng cho site có khách EU hoặc khách quan tâm privacy.
- Pro performance: preload font qua link rel=”preload” as=”font” để giảm FOUT, kiểm soát version, không phụ thuộc CDN bên ngoài.
- Contra setup: mất 30 phút setup (download woff2, upload, viết CSS @font-face), update font phải làm thủ công, không cache cross-site.
Web22 mặc định self-host cho mọi project mới — privacy benefit lớn hơn convenience của CDN. Tool generate woff2 + CSS @font-face là Google Webfonts Helper — chọn font + weight cần, download zip + CSS sẵn.
Cấu hình @font-face chuẩn 2026
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2-variations');
font-weight: 100 900;
font-display: swap;
font-style: normal;
}
Variable font (woff2-variations) load 1 file cho tất cả 9 weight thay vì 9 file riêng — tiết kiệm 60-70% bandwidth. font-display: swap cho phép browser render fallback font ngay, swap khi font load xong, giảm FOIT.
Variable font 2026 — mặc định mới cho design token
Variable font là 1 file chứa multiple axis (weight, width, slant, optical size) thay vì 1 file per weight. Ra mắt 2017, đến 2026 đã trở thành mặc định cho design token + CSS modern.
Ưu điểm rõ ràng về performance và flexibility.
Lợi ích chính của variable font
- Giảm bandwidth 76%: 1 file Inter Variable (~250KB woff2) thay 9 file Inter weight 100-900 (~120KB × 9 = 1,08MB). Cache 1 file hiệu quả cao hơn cache 9 file riêng biệt.
- Arbitrary weight: chỉ variable font support font-weight: 567 (giữa 500 và 600). Designer có flexibility tune fine-grained cho UI cao cấp mà không tốn thêm file.
- Tương lai-proof: design token modern (Style Dictionary, Tokens Studio) generate variable font output mặc định. Static font đang dần out fashion từ 2024.
Axis phổ biến và CSS sử dụng
Axis phổ biến: wght (weight 100-900), wdth (width condensed-expanded), slnt (slant 0° tới -15° cho italic), opsz (optical size auto-tune small / large size).
Inter Variable có 2 axis (wght, slnt). Roboto Flex có 8 axis — flexibility cao nhất nhưng file size lớn hơn 1,5-2 lần.
body {
font-family: 'Inter', system-ui;
font-weight: 400;
}
h1 {
font-weight: 700;
}
.special {
font-weight: 567;
}
Tránh dùng font-variation-settings trực tiếp khi shorthand font-weight đủ — shorthand inherit + cascade tự nhiên hơn. Chỉ dùng variation-settings khi cần axis ngoài weight (slant, width).
Font variable phổ biến 2026
Inter Variable (sans, default Web22), Roboto Flex, Source Sans 3 Variable, Source Serif 4 Variable, Recursive (sans + mono cùng family), Manrope. Tất cả miễn phí trên Google Fonts.
Phía premium có Söhne Variable, GT Walsheim Variable từ foundry trả phí. Brand cao cấp đôi khi đầu tư font premium (1-3k USD license) để khác biệt — nhưng 95% project doanh nghiệp không cần.
Pair fonts — kết hợp heading + body
Pair fonts là kết hợp 2 font cho heading + body. Lựa chọn đúng tạo brand voice rõ, lựa chọn sai khiến site trông tay mơ hoặc inconsistent.
4 pattern phổ biến 2026 dưới đây cover 90% case từ business site tới editorial — chọn theo mood brand và độ dài content.
Pattern 1-2 — Single family và Sans + Serif
- Pattern 1 — Single family (mono-family): 1 font cho cả heading + body với weight khác nhau. Vd Inter (heading 700, body 400).
- Đơn giản, an toàn, performance tốt nhất với 1 file. Phù hợp 70% website business.
- Pattern 2 — Sans + Serif: serif heading + sans body (vd Playfair + Source Sans 3). Tạo contrast classical / modern, phù hợp brand cao cấp, editorial, fashion.
- Cần test cẩn thận vì serif heading có khi quá decorative trên mobile.
Pattern 3-4 — Serif body và Display heading
- Pattern 3 — Sans heading + Serif body: vd Inter + Source Serif 4. Modern + readable.
- Serif body ở size 16-18px dễ đọc lâu, đặc biệt cho long-form content. Phù hợp blog, publishing.
- Pattern 4 — Display + Sans: display font heading (vd Bricolage Grotesque, Fraunces) + sans body. Tạo personality mạnh cho brand.
- Nhưng display font thường nặng (300-500KB) và risky về readability. Chỉ dùng cho heading lớn, không dùng heading nhỏ.
Quy tắc pair: 2 font phải khác mood rõ ràng (sans + serif, display + sans, mono + sans), không 2 sans giống nhau.
Test kết hợp trên 3 page (home, article, form) trước khi commit. Tool fontpair.co hoặc fontjoy.com gen pair tự động khi cần inspiration nhanh.
Performance font — woff2, font-display và FOUT
Web font ảnh hưởng trực tiếp Core Web Vitals 2026 — đặc biệt LCP và CLS. Đây là nguồn lỗi performance phổ biến nhất ở project đơn vị thiếu kỷ luật.
Fix sai 1 lần có thể giảm LCP 1-2 giây.
FOIT vs FOUT — chọn font-display swap
- FOIT (Flash of Invisible Text): browser render text rỗng 100ms-3s chờ font load, sau đó text “pop in”. Mặc định font-display: block.
- UX kém — user thấy layout vỡ trống.
- FOUT (Flash of Unstyled Text): browser render fallback font ngay, swap sang web font khi load xong. font-display: swap. Trải nghiệm tốt hơn FOIT — user đọc được ngay, chỉ có “twitch” nhỏ khi swap.
Chiến lược giảm CLS từ font swap
- Preload web font: qua link rel=”preload” as=”font” type=”font/woff2″ crossorigin trong head. Browser load font sớm, swap nhanh hơn.
- Chỉ preload 1-2 font critical, không preload mọi weight.
- Match fallback font metrics: giảm CLS khi swap. Tool Capsize hoặc CSS Font Loading API.
- Tailwind 3.4+ tự gen @font-face với size-adjust, ascent-override, descent-override để fallback gần giống web font.
- Subset font: chỉ load glyph cần thiết (Latin + Vietnamese), bỏ Cyrillic, CJK. Giảm 40-60% file size.
- Google Webfonts Helper có option chọn subset trực tiếp lúc download.
- Variable font: như giải thích ở phần trước, 1 file thay 9 — giảm bandwidth, cache hiệu quả hơn.
Đo CLS từ font swap
Mở Chrome DevTools → Performance → record load page. Xem tiến độ “Layout Shift” — nếu thấy shift sau 200-1000ms với label “font swap”, đó là CLS từ font.
Fix bằng size-adjust và preload.
CLS từ font thường nhỏ (0,02-0,05) nhưng tích luỹ qua nhiều element làm tổng CLS vượt 0,1 (ngưỡng “Good” của Google). Đo trên trang dài (article 3000 từ) để bắt CLS tổng thực tế.
Câu hỏi thường gặp về typography web
Dùng font hệ thống (system-ui) thay web font có được không?
Được, đặc biệt cho dashboard SaaS / app nội bộ. font-family: system-ui dùng San Francisco trên Apple, Segoe UI trên Windows, Roboto trên Android — performance tốt nhất với 0KB load, familiar với user.
Hạn chế là brand voice yếu — mỗi user thấy khác nhau. Web22 dùng cho admin panel + dashboard nội bộ, không dùng cho trang tiếp thị cần brand voice rõ.
Bao nhiêu font weight là đủ cho website business?
2-3 weight đủ cho 90% case. 400 regular (body), 600 semibold hoặc 700 bold (heading + emphasis), tuỳ chọn 500 medium (button + label).
Variable font không có vấn đề này — load 1 file, dùng arbitrary weight. Static font cần load 3 weight max, mỗi weight ~80-150KB woff2 — đừng nhồi 6-8 weight chỉ để “đẹp”.
Vietnamese font support có cần subset riêng không?
Inter, Source Sans 3, Roboto, Open Sans, Lato đều support full Vietnamese (đầy đủ dấu đ + nguyên âm có dấu). Khi subset chọn “vietnamese” + “latin” trên Google Webfonts Helper là đủ.
Một số font display ngoại không có vietnamese subset — test trước khi commit. Tránh font không có dấu đ vì sẽ render thành ô vuông trên mobile.
Font pair nào phù hợp cho website doanh nghiệp Việt Nam 2026?
Web22 đề xuất 3 kết hợp chuẩn. Inter Variable (mono-family, an toàn, modern).
Inter + Source Serif 4 Variable (sans heading + serif body, readable cho long content). Bricolage Grotesque + Inter (display heading + sans body, personality mạnh).
Tất cả 3 đều free, support Vietnamese, có variable version. Kết hợp 1 phù hợp 70% case, kết hợp 2 cho blog/publishing, kết hợp 3 cho brand muốn nổi bật.
Mobile có cần đổi font khác desktop không?
Không. Một font cho cả mobile + desktop.
Chỉ scale size xuống (1 step modular scale), giữ line-height + measure. Đổi font theo viewport làm UX không nhất quán + tăng bandwidth (load 2 font).
Nếu thấy font không đủ readable trên mobile, vấn đề thường là size + line-height + contrast chứ không phải font sai — fix 3 thứ đó trước khi nghĩ tới đổi font.
Tài nguyên và bước tiếp theo
Typography là 1 trong 6 thành phần UI cốt lõi. Sau khi xây type system chuẩn, cần phối hợp với color + spacing + grid để hoàn thiện design system.
Các bài liên quan trong cụm UI/UX cơ bản:
- UI/UX là gì — định nghĩa, 5 layer UX và 6 thành phần UI cốt lõi — typography là 1 trong 6 thành phần, đặt trong context tổng thể.
- 7 nguyên tắc thiết kế UI — checklist mỗi screen cần verify — typography liên quan trực tiếp hierarchy và consistency.
- Màu sắc trong thiết kế UI — 60-30-10 và WCAG contrast — cặp typography + color tạo readability hoàn chỉnh.
- White space trong thiết kế — spacing scale 8pt và token chuẩn — line-height và paragraph spacing là white space trong typography.
- Đội UI Designer Web22 — wireframe + handoff Dev Mode — gói trọn gói có handoff Figma + CSS variable token + dev guideline performance.
Cần đội Web22 xây type system chuẩn web với modular scale + variable font + woff2 self-host + audit Core Web Vitals? Đội UI Designer Web22 — wireframe + handoff Dev Mode — gói trọn gói có handoff Figma + CSS variable token + dev guideline performance.


