Khi một trang gọi web font (font web — phông chữ tải từ máy chủ), trình duyệt phải chờ file font về mới biết vẽ chữ ra sao. Trong lúc chờ đó, mặc định nhiều trình duyệt giấu luôn chữ — người dùng nhìn vào một khoảng trống. Descriptor font-display chính là cái nút điều khiển hành vi này, và swap là giá trị phổ biến nhất.
FOIT và FOUT — hai cách trình duyệt xử lý lúc chờ font
Có hai kịch bản khi web font chưa tải xong:
- FOIT (Flash of Invisible Text — chớp chữ vô hình): trình duyệt giấu chữ, để khoảng trống cho tới khi web font về. Người dùng thấy trang như thiếu nội dung.
- FOUT (Flash of Unstyled Text — chớp chữ chưa định dạng): trình duyệt vẽ chữ ngay bằng font dự phòng của hệ thống, rồi đổi sang web font khi tải xong. Người dùng đọc được nội dung ngay, nhưng có một nhịp chữ “nhảy” kiểu khi đổi font.
font-display: swap chọn hướng FOUT: ưu tiên cho người dùng đọc được chữ sớm thay vì nhìn khoảng trống. Đây là lựa chọn an toàn cho hầu hết website nội dung, vì chữ là thứ người ta vào trang để đọc.

Cơ chế của font-display swap
Mỗi giá trị font-display chia thời gian tải font thành hai giai đoạn: block period (giai đoạn chặn — chữ vô hình, chờ web font) và swap period (giai đoạn đổi — đã vẽ bằng font dự phòng, sẵn sàng đổi sang web font khi nó về).
Với swap, block period gần như bằng 0 và swap period là vô hạn. Nghĩa là: vẽ chữ bằng font dự phòng gần như tức thì, và dù web font về muộn cỡ nào trình duyệt cũng vẫn đổi sang nó. Cách khai báo trong @font-face:
@font-face{
font-family: "Inter";
src: url("/fonts/inter.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}Vì font-display là một descriptor đặt bên trong @font-face, mỗi khối font khai báo riêng — bạn có thể để body chữ dùng swap còn một font icon nào đó dùng giá trị khác.
Phân biệt swap, fallback và optional
Ba giá trị này chỉ khác nhau ở độ dài hai giai đoạn nói trên, dẫn tới ba triết lý xử lý khác nhau:
| Giá trị | Block period | Swap period | Hệ quả thực tế |
|---|---|---|---|
swap | gần như 0 | vô hạn | Chữ hiện ngay; web font luôn được đổi vào dù về muộn. Có thể gây xê dịch. |
fallback | rất ngắn (~100ms) | ngắn | Có chớp chặn cực ngắn; nếu font về quá muộn thì bỏ luôn, giữ font dự phòng. |
optional | rất ngắn (~100ms) | không có | Font về kịp trong ~100ms thì dùng, không kịp thì dùng font dự phòng cả lượt — gần như không xê dịch. |
Nói gọn: swap đặt cược vào việc “luôn cho người dùng thấy web font”, trả giá bằng nguy cơ chữ nhảy. optional đặt cược vào sự ổn định thị giác, chấp nhận có lần người dùng chỉ thấy font hệ thống. Lựa chọn phụ thuộc vào việc bạn coi bản sắc thương hiệu (đúng phông) hay sự ổn định layout quan trọng hơn.
font-display swap và xê dịch layout (CLS)
Mặt trái của swap liên quan thẳng tới CLS (Cumulative Layout Shift — tổng mức xê dịch bố cục). Khi đổi từ font dự phòng sang web font, nếu hai phông có kích thước chữ khác nhau (cao thấp, rộng hẹp khác nhau), khối văn bản sẽ thay đổi chiều cao và đẩy nội dung phía dưới nhảy chỗ. Đó chính là một nguồn xê dịch mà người dùng cảm nhận rõ.
Trong bộ Core Web Vitals hiện hành (LCP ≤ 2,5s, INP ≤ 200ms, CLS ≤ 0,1 — đo ở phân vị 75 của người dùng thật), CLS là chỉ số dễ bị font swap kéo lùi nhất. Tin tốt: bạn không phải bỏ swap để cứu CLS. Cách làm hiện đại là cho font dự phòng “khoác số đo” của web font, để lúc swap gần như không có thay đổi kích thước.
Bốn descriptor giúp việc này, đặt vào một @font-face mô tả font dự phòng:
@font-face{ font-display:swap;
font-family: "Inter-fallback";
src: local("Arial");
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
body {
font-family: "Inter", "Inter-fallback", sans-serif;
}size-adjust, ascent-override, descent-override và line-gap-override điều chỉnh số đo của font hệ thống cho khớp web font. Theo hướng dẫn của web.dev, khi canh đúng, lúc đổi font “gần như không có thay đổi thị giác — một cú swap mượt”. Bạn có thể tự dò các con số bằng công cụ tạo fallback font, hoặc dùng các plugin/framework sinh tự động.
Web22 vận hành web22.dev trên LiteSpeed kèm Cloudflare và dùng đúng font-display: swap cho font chính, kèm self-host (tự đặt font trên máy chủ thay vì gọi sang Google) để chữ về nhanh — đây là lựa chọn thực chiến cho site nội dung, ưu tiên người đọc thấy chữ sớm. Muốn tải font nhanh thêm, xem cách self-host Google Font; muốn truy mọi nguyên nhân nhảy chỗ, xem cách khắc phục CLS do layout shift.

Khi nào nên dùng giá trị nào
- Website nội dung, blog, trang dịch vụ: dùng
swapkèm fallback đã canh số đo. Người đọc thấy chữ ngay, đúng phông thương hiệu, mà vẫn ổn định. - Trang siêu nhạy về ổn định thị giác (ví dụ checkout, app đo CLS gắt): cân nhắc
optionalđể gần như triệt tiêu xê dịch, chấp nhận đôi khi không hiện đúng phông. - Font icon hoặc font phụ không quan trọng: có thể để
swaphoặcfallbacktuỳ mức cần thiết.
Câu hỏi thường gặp
font-display swap có làm trang nhanh hơn không?
Nó không giảm dung lượng font, nhưng giúp người dùng thấy chữ sớm hơn (cải thiện cảm nhận tốc độ và đôi khi cả LCP nếu phần tử lớn nhất là văn bản). Để nhanh thật, cần kết hợp self-host và nén font woff2.
swap có chắc chắn gây CLS không?
Không chắc chắn, nhưng có nguy cơ nếu font dự phòng và web font khác kích thước. Canh fallback bằng size-adjust và các override sẽ đưa xê dịch về gần 0.
Không khai báo font-display thì sao?
Mặc định trình duyệt thường xử theo kiểu chặn chữ một lúc (gần với FOIT), tức người dùng có thể thấy khoảng trống. Khai báo rõ swap hoặc optional luôn tốt hơn để chủ động.
Nếu font đang khiến trang của bạn bị chữ vô hình hoặc nhảy layout, dịch vụ tối ưu tốc độ website của Web22 có thể giúp canh lại chiến lược tải font cho gọn.
