title | author | date |
---|---|---|
Chơi chữ cùng Variable Fonts |
hai |
12-13-2022 |
Trước khi có variable fonts, mỗi kiểu chữ trong 1 loại font được chia thành file riêng biệt.
Với variable fonts, tất cả các kiểu chữ có thể được chứa trong 1 file.
. Traditional fonts
├── static/Inter-Thin.ttf
├── static/Inter-ExtraLight.ttf
├── static/Inter-Light.ttf
├── static/Inter-Regular.ttf
├── static/Inter-Medium.ttf
├── static/Inter-SemiBold.ttf
├── static/Inter-Bold.ttf
├── static/Inter-ExtraBold.ttf
├── static/Inter-Black.ttf
└── static/Inter-Thin.ttf
. Variable fonts
└── Inter-VariableFont_slnt,wght.ttf
Variable fonts cung cấp một tập hợp các axes
(số nhiều của axis) khác nhau tuỳ vào người thiết kế và phát triển font.
Thường chia thành hai loại axes:
- Axes có sẵn (registered axes) gồm
weight
,width
,optical size
,slant
vàitalics
- Axes tuỳ biến (custom axes) có số lượng phụ thuộc vào sự sáng tạo của người thiết kế
Để phân biệt với registered axes, tag của custom axes sẽ được viết hoa.
Axis name | CSS value |
---|---|
Weight | wght |
Width | wdth |
Slant | slnt |
Optical Size | opsz |
Italics | ital |
Để dễ hình dùng hơn ta hãy dùng hệ tọa độ mặt phẳng XY làm ví dụ.
- Trục X = weight, có giá trị từ 300 đến 1000
- Trục Y = casual, có giá trị từ 0 đến 1
Với mỗi tọa độ khác nhau sẽ cho ra một kiểu chữ khác nhau. Mỗi variable font sẽ có hệ trục khác nhau, và giá trị của mỗi trục cũng khác nhau luôn.
Multiverse of axis <=> more axes more styles.
Theo kinh nghiệm cá nhân thì có 3 cách:
- Dùng tool như Wakamai Fondue
- Dùng Type Tester trên Google Fonts (chỉ áp dụng với fonts được host trên này)
- Dùng Safari Devtool là nhanh nhất (Chrome Devtool và Firefox Devtool không có)
- Tiết kiệm dung lượng tới mức đáng kể so với tổng các file fonts gộp lại.
- Tăng trải nghiệm và lựa chọn thiết kế với nhiều kiểu chữ khác nhau.
- Giảm độ trễ network request => tăng thời gian render trang web.
- Font animation (Anicons)
Variable fonts cũng tương tự traditional fonts về cơ chế khai báo, tùy vào tooling và hosting sẽ có cách khai báo khác nhau.
import { Recursive } from "@next/font/google";
const recursive = Recursive({
display: "swap",
axes: ["slnt", "MONO", "CRSV", "CASL"],
});
Ví dụ trên sử dụng @next/font
để khai báo Recursive với 1 registered và 3 custom axes.
wght
axis có thể được set bằngfont-weight
, thay vì các keyword như medium|semibold|bold, hãy thoải mái dùng giá trị nằm trong range cho phép.wdth
axis thì dùngfont-stretch
ital
axis thường mang giá trị on/off, dùngfont-style: italic/normal
slnt
axis cũng là chữ nghiêng nhưng không phải italic, nó khiến cho chữ nghiêng theo 1 góc nhất định, dùngfont-style: oblique <angle>
opsz
axis khá hiếm dùng, hữu ích cho việc thay đổi chi tiết ký tự ở các kích thước khác nhau, dùngfont-optical-sizing
Tuy nhiên có những font bị hạn chế bởi CSS Specs chưa đáp ứng được, nên họ sẽ set giá trị axis qua font-variation-settings
giống như custom axes
.between-regular-and-medium {
/* Should be font-weight: 450; */
font-variation-settings: "wght" 450;
}
.stretch {
/* Should be font-stretch: 22; */
font-variation-settings: "wdth" 22;
}
.italic {
/* Should be font-style: italic; */
font-variation-settings: "ital" 1;
}
.slanted {
/* Should be font-style: oblique 10deg; */
font-variation-settings: "slnt" 10;
}
.optical-size {
/* Should be font-optical-sizing: 8pt; */
font-variation-settings: "opsz" 8;
}
Chỉ có font-variation-settings
mới đáp ứng được các giá trị của custom axes. Ví dụ Roboto Flex có Grade axis (GRAD
).
.grade-light {
font-variation-settings: "GRAD" -200;
}
.grade-normal {
font-variation-settings: "GRAD" 0;
}
.grade-heavy {
font-variation-settings: "GRAD" 150;
}
Một vấn đề của font-variation-settings
đó là không có tính kế thừa. Axis nào mà không được khai báo thì sẽ tự động reset về giá trị mặc định.
Cùng xem ví dụ dưới đây:
<span class="slanted grade-light">
I should be slanted and have a light grade
</span>
Đầu tiên là font-variation-settings: 'slnt' 10
được apply, sau đó là font-variation-settings: "GRAD" -200
, tuy nhiên slnt
axis sẽ bị reset về 0 vì chỉ nhận được giá trị của GRAD
. Kết quả là đoạn text trên sẽ không có độ nghiêng mong muốn.
Để giải quyết vấn đề này cần dùng tới CSS Variables:
:root {
--slnt: 0;
--GRAD: 0;
}
.slanted {
--slnt: 10;
}
.grade-light {
--grad: -200;
}
.slanted,
.grade-light {
font-variation-settings: "slnt" var(--slnt), "GRAD" var(--GRAD);
}