CSS font-variation 可變字體的魅力(實(shí)例詳解)
今天,在 CodePen 上看到一個(gè)很有意思的效果 -- GSAP 3 ETC Variable Font Wave,借助了 JS 動(dòng)畫庫(kù) GSAP 實(shí)現(xiàn),一起來(lái)看看:

我尋思著能否使用 CSS 復(fù)刻一版,鼓搗了一會(huì),利用純 CSS 成功實(shí)現(xiàn)了原效果。
上述效果,最核心的就是文字的動(dòng)畫,文字從較細(xì)貼著較緊,到較粗隔著較遠(yuǎn)不斷變化。有人會(huì)認(rèn)為這里是 transform: scale(),實(shí)則不然。
scale 是等比例放大縮小一個(gè)物體,而仔細(xì)觀察上述效果,明顯是有字體的粗細(xì)、字體的字寬的變化。這里,其實(shí)用到了 CSS 比較新的特性 -- 可變字體,也就是 font-variation。
本文,將借助這個(gè)效果,介紹一下什么是 CSS font-variation。
什么是 CSS font-variation,可變字體?
根據(jù) MDN -- Variable fonts,可變字體(Variable fonts)是 OpenType 字體規(guī)范上的演進(jìn),它允許將同一字體的多個(gè)變體統(tǒng)合進(jìn)單獨(dú)的字體文件中。從而無(wú)需再將不同字寬、字重或不同樣式的字體分割成不同的字體文件。我們只需通過(guò)CSS與一行 @font-face 引用,即可獲取包含在這個(gè)單一文件中的各種字體變體。
emm,概念有點(diǎn)難理解,簡(jiǎn)單解釋一下。
與可變字體對(duì)應(yīng)的,是標(biāo)準(zhǔn)(靜態(tài))字體。
標(biāo)準(zhǔn)(靜態(tài))字體就是只代表字體的某一特定的寬度/字重/樣式的組合的字體文件,通常我們?cè)陧?yè)面引入的字體文件都是這種,只代表這個(gè)字體的某一特定的寬度/字重/樣式的組合。
而如果我們想引入一個(gè)字體家族(譬如 Roboto 字體族),它可能包含了 “Roboto Regular”(常規(guī)字重)、“Roboto Bold”(粗體),或是 “Roboto Bold Italic”(粗體+斜體) 等一系列字體文件。這意味著我們可能需要 20 或 30 個(gè)不同的字體文件才能算是有了一整個(gè)字體家族(對(duì)于有著不同寬度的大型字體來(lái)說(shuō),這個(gè)數(shù)量還要翻上幾倍)。
而可變字體 -- font-variation,可以將它理解為 all in one,通過(guò)使用可變字體,所有字重、字寬、斜體等情況的排列組合都可以被裝進(jìn)一個(gè)文件中。當(dāng)然,這個(gè)文件可能比常規(guī)的單個(gè)字體文件大一些。
靜態(tài)字體的局限性
舉個(gè)例子,在 Google Font,我隨便選取一個(gè)標(biāo)準(zhǔn)靜態(tài)字體,實(shí)現(xiàn)一個(gè)字體 font-weight 的變化動(dòng)畫:
<p>CSS font-variation</p> <p>CSS font-variation</p> <p>CSS font-variation</p> <p>CSS font-variation</p> <p>CSS font-variation</p> <p>CSS font-variation</p>
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@300&display=swap');
p {
font-family: 'Lato', sans-serif;
font-size: 48px;
}
p:nth-child(1) {
font-weight: 100;
}
p:nth-child(2) {
font-weight: 200;
}
p:nth-child(3) {
font-weight: 300;
}
p:nth-child(4) {
font-weight: 400;
}
p:nth-child(5) {
font-weight: 500;
}
p:nth-child(6) {
font-weight: 600;
}
看看結(jié)果:

并沒(méi)有我們想象中的,因?yàn)樽煮w粗細(xì)從 100 到 600,所以字體依次變粗的情況,一共只有兩種字重:
- 當(dāng)
font-weight:處于 100 - 500 的時(shí)候,其實(shí)都是font-weight: normal; - 當(dāng)
font-weight: 600的時(shí)候,其實(shí)是命中了font-weight: bold。
這個(gè)也就是傳統(tǒng)靜態(tài)字體的局限性,單一字體文件中,其實(shí)是不會(huì)有該字體的所有粗細(xì)、字寬的類型的。
可變字體的多樣性
接下來(lái),我們換上可變字體。
加載可變字體的語(yǔ)法與其他 web 字體非常相似,但有一些顯著的差異,這些差異是通過(guò)對(duì)現(xiàn)代瀏覽器中可用的傳統(tǒng) @font-face 語(yǔ)法的升級(jí)提供的。 基本語(yǔ)法是相同的,但是字體技術(shù)是不一樣的,并且可變字體可以提供像對(duì) font-weight 和 font-stretch 等描述符的允許范圍,而不是根據(jù)加載的字體文件來(lái)命名。 下面,我們將加載一個(gè)支持字體粗細(xì)從 100 到 900,字體伸縮變形支持從 10% 到 400% 的 AnyBody 可變字體。
@font-face {
font-family: 'Anybody';
src: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/61488/ETCAnybodyPB.woff2') format('woff2-variations');
font-display: block;
font-style: normal italic;
font-weight: 100 900;
font-stretch: 10% 400%;
}
p {
font-family: 'Anybody', sans-serif;
font-size: 48px;
}
p:nth-child(1) {
font-weight: 100;
}
// ...
p:nth-child(6) {
font-weight: 600;
}
同樣是設(shè)定字體粗細(xì)從 100 - 600,效果如下:
這一次,可以看到,字體有明顯的均勻變化,支持 font-weight: 100 到 font-weight: 600 的逐漸變化。這兒就是可變字體的魅力。
理解 font-variation-settings
除了直接通過(guò) font-weight 去控制可變字體的粗細(xì),CSS 還提供了一個(gè)新的屬性 font-variation-settings 去同時(shí)控制可變字體的多個(gè)屬性。
可變字體新格式的核心是可變軸的概念,其描述了字體設(shè)計(jì)中某一特性的允許變化范圍。
所有可變字體都有至少有 5 個(gè)可以通過(guò) font-variation-settings 控制的屬性軸,它們屬于注冊(cè)軸(registered),能夠映射現(xiàn)有的 CSS 屬性或者值。
它們是:
- 字重軸 "wght":對(duì)應(yīng)
font-weight,控制字體的粗細(xì) - 寬度軸 "wdth":對(duì)應(yīng)
font-stretch,控制字體的伸縮 - 斜度軸 "slnt" (slant):對(duì)應(yīng)字體的
font-style: oblique + angle,控制字體的傾斜 - 斜體軸 "ital":對(duì)應(yīng)字體的
font-style: italic,控制字體的傾斜(注意,和font-style: oblique是不一樣的傾斜) - 光學(xué)尺寸軸 "opsz":對(duì)應(yīng)字體的
font-optical-sizing,控制字體的光學(xué)尺寸
好吧,可能會(huì)有一點(diǎn)點(diǎn)懵,沒(méi)事,通過(guò)一個(gè)例子馬上就能理解什么意思。
還是利用上述的可變字體,我們利用 font-variation-settings 實(shí)現(xiàn)一個(gè)字體粗細(xì)的變化的動(dòng)畫:
<p>Anybody</p>
@font-face {
font-family: 'Anybody';
src: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/61488/ETCAnybodyPB.woff2') format('woff2-variations');
font-display: block;
font-style: normal italic;
font-weight: 100 900;
font-stretch: 10% 400%;
}
p {
font-family: 'Anybody';
font-size: 48px;
animation: fontWeightChange 2s infinite alternate linear;
}
@keyframes fontWeightChange {
0% {
font-variation-settings: 'wght' 100;
}
100% {
font-variation-settings: "wght" 600;
}
}
效果如下:

其中,其實(shí)可以理解為,利用了 font-variation-settings: "wght" 的變化的動(dòng)畫,等同于 font-weight 變化動(dòng)畫:

利用 font-variation-settings 進(jìn)行字體的多個(gè)特征同時(shí)變化
OK,那么如果既然是一樣的效果,為什么還要多此一舉搞個(gè) font-variation-settings 呢?
那是因?yàn)?font-variation-settings 除了支持字體的粗細(xì)變化外,還支持上述說(shuō)的注冊(cè)軸設(shè)定的多個(gè)樣式屬性變化,以及自定義軸的一些字體樣式屬性變化。
這次,除了字體粗細(xì)外,我們?cè)偬砑由?"wdth" 的變化,也就是字體的伸縮。
<p>Anybody</p>
@font-face {
font-family: 'Anybody';
src: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/61488/ETCAnybodyPB.woff2') format('woff2-variations');
font-display: block;
font-style: normal italic;
font-weight: 100 900;
font-stretch: 10% 400%;
}
p {
font-family: 'Anybody';
font-size: 48px;
animation: fontWeightChange 2s infinite alternate linear;
}
@keyframes fontWeightChange {
0% {
font-variation-settings: 'wght' 100, 'wdth' 60;
}
100% {
font-variation-settings: "wght" 600, 'wdth' 400;
}
}
這次,進(jìn)行的是字體粗細(xì)從 100 到 600,字體伸縮從 60% 到 400% 的動(dòng)畫效果,效果如下:

也就是說(shuō),font-variation-settings 是同時(shí)支持多個(gè)字體樣式一起變化的,這一點(diǎn)非常重要。
到這里,其實(shí)我們已經(jīng)可以利用這個(gè)實(shí)現(xiàn)題圖所示的效果了,我們簡(jiǎn)單改造下,添加多行,再給每行設(shè)定一個(gè)負(fù)的動(dòng)畫延遲即可:
<div class="g-container">
<ul>
<li>ANYBODY</li>
<li>ANYBODY</li>
<li>ANYBODY</li>
<li>ANYBODY</li>
<li>ANYBODY</li>
<li>ANYBODY</li>
<li>ANYBODY</li>
<li>ANYBODY</li>
</ul>
</div>
借助 SCSS 簡(jiǎn)化下代碼,下述代碼核心就是給每個(gè) li,添加一個(gè)相同的動(dòng)畫 font-variation-settings 動(dòng)畫,并且依次設(shè)置了等差的 animation-delay:
li {
animation: change 0.8s infinite linear alternate;
}
@for $i from 1 to 9 {
li:nth-child(#{$i}) {
animation-delay: #{($i - 1) * -0.125}s;
}
}
@keyframes change {
0% {
font-variation-settings: 'wdth' 60, 'wght' 100;
opacity: .5;
}
100% {
font-variation-settings: 'wdth' 400, 'wght' 900;
opacity: 1;
}
}
效果如下:

好,接下來(lái),利用 CSS 3D 簡(jiǎn)單構(gòu)造一下 3D 場(chǎng)景即可,完整的 CSS 代碼如下:
@font-face {
font-family: 'Anybody';
src: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/61488/ETCAnybodyPB.woff2') format('woff2-variations');
font-display: block;
font-style: normal italic;
font-weight: 100 900;
font-stretch: 10% 400%;
}
.g-container {
position: relative;
margin: auto;
display: flex;
font-size: 48px;
font-family: 'Anybody';
color: #fff;
transform-style: preserve-3d;
perspective: 200px;
}
ul {
background: radial-gradient(farthest-side at 110px 0px, rgba(255, 255, 255, 0.2) 0%, #171717 100%);
padding: 5px;
transform-style: preserve-3d;
transform: translateZ(-60px) rotateX(30deg) translateY(-30px);
animation: move 3s infinite alternate;
&::before {
content: "";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 45px;
background: #141313;
transform: rotateX(-230deg);
transform-origin: 50% 100%;
}
}
li {
width: 410px;
animation: change 0.8s infinite linear alternate;
}
@for $i from 1 to 9 {
li:nth-child(#{$i}) {
animation-delay: #{($i - 1) * -0.125}s;
}
}
@keyframes change {
0% {
font-variation-settings: 'wdth' 60, 'wght' 100;
opacity: .5;
}
100% {
font-variation-settings: 'wdth' 400, 'wght' 900;
opacity: 1;
}
}
@keyframes move {
100% {
transform: translateZ(-60px) rotateX(30deg) translateY(0px);
}
}
效果如下,我們就基本還原了題圖的效果:

完整的代碼及 DEMO 效果你可以戳這里:CodePen Demo -- Pure CSS Variable Font Wave
font-variation 的可變軸 -- 注冊(cè)軸與自定義軸
回歸到可變字體本身。上面提到了可變軸這個(gè)概念,它們分為注冊(cè)軸與自定義軸,英文是:
- 注冊(cè)軸 - registered axes
- 自定義軸 - custom axes
可變字體新格式的核心是可變軸的概念,其描述了字體設(shè)計(jì)中某一特性的允許變化范圍。
例如‘字重軸’描述了字體的粗細(xì);“寬度軸”描述了字體的寬窄;“斜體軸”描述是否使用斜體字形并且可相應(yīng)地開關(guān);等。請(qǐng)注意,軸既可以是范圍選擇又可以是開關(guān)選擇。字重可能在1-999之間,而斜體可能只是簡(jiǎn)單的0或1(關(guān)閉或打開)。
如規(guī)范中所定義,存在兩種變形軸,注冊(cè)軸和自定義軸:
- 注冊(cè)軸最為常見(jiàn),常見(jiàn)到制定規(guī)范的作者認(rèn)為有必要進(jìn)行標(biāo)準(zhǔn)化。 目前注冊(cè)的五個(gè)軸是字重,寬度,傾斜度,斜體和光學(xué)尺寸。
上文其實(shí)已經(jīng)羅列了 5 個(gè)注冊(cè)軸,并且簡(jiǎn)單介紹了它們的使用。再羅列一次:
- 字重軸 "wght":對(duì)應(yīng)
font-weight,控制字體的粗細(xì) - 寬度軸 "wdth":對(duì)應(yīng)
font-stretch,控制字體的伸縮斜度軸 "slnt" (slant):對(duì)應(yīng)字體的font-style: oblique + angle,控制字體的傾斜 - 斜體軸 "ital":對(duì)應(yīng)字體的
font-style: italic,控制字體的傾斜(注意,和font-style: oblique是不一樣的傾斜) - 光學(xué)尺寸軸 "opsz":對(duì)應(yīng)字體的
font-optical-sizing,控制字體的光學(xué)尺寸自定義軸實(shí)際上是無(wú)限的:字體設(shè)計(jì)師可以定義和界定他們喜歡的任何軸,并且只需要給它一個(gè)四個(gè)字母的標(biāo)簽以在字體文件格式本身中識(shí)別它。
我們來(lái)看一個(gè) 自定義軸 的例子:
<p>Grade</p>
p {
font-family: "Amstelvar VF", serif;
font-size: 64px;
font-variation-settings: 'GRAD' 88;
}
上述 font-family: "Amstelvar VF" 是一個(gè)可變字體,而 'GRAD' 屬于自定義軸的一個(gè),意為等級(jí)軸。
等級(jí)軸 'GRAD':“等級(jí)”一詞指的是字體設(shè)計(jì)的相對(duì)重量或密度,但與傳統(tǒng)的“重量”不同之處在于文本占據(jù)的物理空間不會(huì)改變,因此改變文本等級(jí)并不會(huì)改變文本或其周圍元素的整體布局。 這使得等級(jí)成為有用的變化軸,因?yàn)樗梢宰兓騽?dòng)畫而不會(huì)引起文本本身的回流。
MDN 上有關(guān)于改變 'GRAD' 的值,對(duì)應(yīng)字體變化的一個(gè) DEMO,效果如下:

值得注意的是,自定義軸可以是字體設(shè)計(jì)師想象的任何設(shè)計(jì)變化軸??赡苡幸恍?huì)逐漸變得相當(dāng)普遍,隨著規(guī)范的發(fā)展甚至演變成注冊(cè)軸。
去哪找可變字體?
OK,如果現(xiàn)在我想在業(yè)務(wù)中使用一下可變字體,去實(shí)現(xiàn)一個(gè)效果或者動(dòng)畫,可以上哪里尋找可變字體的資源呢?
這里有一個(gè)很不錯(cuò)的網(wǎng)站 -- Variable Fonts。
上面收集了非常多的 Variable Fonts,并且羅列出了它們?cè)谧?cè)軸上支持的字體屬性的范圍,譬如支持字重從 100 到 700,我們可以自由進(jìn)行調(diào)試預(yù)覽

Can i Use(2022-02-20)
現(xiàn)在能夠開始使用可變字體了嗎?
截止至今天,Can i Use 的截圖:

兼容性已經(jīng)非常的不錯(cuò)了,不考慮 IE 系列的話可以上到實(shí)際的生產(chǎn)環(huán)境中去。
最后
本文到此結(jié)束,希望對(duì)你有幫助
更多精彩 CSS 技術(shù)文章匯總在我的 Github -- iCSS ,持續(xù)更新,歡迎點(diǎn)個(gè) star 訂閱收藏。
到此這篇關(guān)于CSS font-variation 可變字體的魅力(實(shí)例詳解)的文章就介紹到這了,更多相關(guān)CSS font-variation 可變字體內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章
這篇文章主要介紹了 css常用字體屬性與背景屬性,css可以做出很多使html樣式的改變,今天主要說(shuō)一說(shuō)字體樣式與背景樣式,字體樣式的分類根據(jù)名字就可以判斷出來(lái),下面文章的2022-02-25
讓我來(lái)教你使用css中的字體圖標(biāo)的方法
這篇文章主要介紹了讓我來(lái)教你使用css中的字體圖標(biāo)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-17
這篇文章主要介紹了CSS字體、文本、列表屬性的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-22




