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è)軸最為常見,常見到制定規(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