关于前端:突破限制CSS-fontvariation-可变字体的魅力

6次阅读

共计 7407 个字符,预计需要花费 19 分钟才能阅读完成。

明天,在 CodePen 上看到一个很有意思的成果 — GSAP 3 ETC Variable Font Wave,借助了 JS 动画库 GSAP 实现,一起来看看:

我寻思着是否应用 CSS 复刻一版,鼓捣了一会,利用纯 CSS 胜利实现了原成果。

上述成果,最外围的就是文字的动画,文字从 较细贴着较紧 ,到 较粗隔着较远 一直变动。有人会认为这里是 transform: scale(),实则不然。

scale 是等比例放大放大一个物体,而仔细观察上述成果,显著是有字体的粗细、字体的字宽的变动。这里,其实用到了 CSS 比拟新的个性 — 可变字体,也就是 font-variation

本文,将借助这个成果,介绍一下什么是 CSS font-variation。

什么是 CSS font-variation,可变字体?

依据 MDN — Variable fonts,可变字体(Variable fonts)是 OpenType 字体标准上的演进,它容许将同一字体的多个变体统合进独自的字体文件中。从而无需再将不同字宽、字重或不同款式的字体宰割成不同的字体文件。咱们只需通过 CSS 与一行 @font-face 援用,即可获取蕴含在这个繁多文件中的各种字体变体。

emm,概念有点难了解,简略解释一下。

与可变字体对应的,是规范(动态)字体。

规范(动态)字体就是只代表字体的某一特定的宽度 / 字重 / 款式的组合的字体文件,通常咱们在页面引入的字体文件都是这种,只代表这个字体的某一特定的宽度 / 字重 / 款式的组合。

而如果咱们想引入一个字体家族(譬如 Roboto 字体族),它可能蕴含了“Roboto Regular”(惯例字重)、“Roboto Bold”(粗体),或是“Roboto Bold Italic”(粗体 + 斜体)等一系列字体文件。这意味着咱们可能须要 20 或 30 个不同的字体文件能力算是有了一整个字体家族(对于有着不同宽度的大型字体来说,这个数量还要翻上几倍)。

而可变字体 — font-variation,能够将它了解为 all in one,通过应用可变字体,所有字重、字宽、斜体等状况的排列组合都能够被装进一个文件中。当然,这个文件可能比惯例的单个字体文件大一些。

动态字体的局限性

举个例子,在 Google Font,我轻易选取一个规范动态字体,实现一个字体 font-weight 的变动动画:

<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>

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;}

看看后果:

并没有咱们设想中的,因为字体粗细从 100 到 600,所以字体顺次变粗的状况,一共只有两种字重:

  1. font-weight: 处于 100 – 500 的时候,其实都是 font-weight: normal;
  2. font-weight: 600 的时候,其实是命中了 font-weight: bold

这个也就是传统动态字体的局限性,繁多字体文件中,其实是不会有该字体的所有粗细、字宽的类型的。

可变字体的多样性

接下来,咱们换上可变字体。

加载可变字体的语法与其余 web 字体十分类似,但有一些显著的差别,这些差别是通过对古代浏览器中可用的传统 @font-face 语法的降级提供的。

根本语法是雷同的,然而字体技术是不一样的,并且可变字体能够提供像对 font-weightfont-stretch 等描述符的容许范畴,而不是依据加载的字体文件来命名。

上面,咱们将加载一个反对字体粗细从 100900,字体伸缩变形反对从 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;}

同样是设定字体粗细从 100 – 600,成果如下:

这一次,能够看到,字体有显著的平均变动,反对 font-weight: 100font-weight: 600 的逐步变动。这儿就是可变字体的魅力。

了解 font-variation-settings

除了间接通过 font-weight 去管制可变字体的粗细,CSS 还提供了一个新的属性 font-variation-settings 去同时管制可变字体的多个属性。

可变字体新格局的外围是 可变轴的概念,其形容了字体设计中某一个性的容许变动范畴。

所有可变字体都有至多有 5 个能够通过 font-variation-settings 管制的属性轴,它们属于注册轴(registered),可能映射现有的 CSS 属性或者值。

它们是:

  • 字重轴 “wght”:对应 font-weight,管制字体的粗细
  • 宽度轴 “wdth”:对应 font-stretch,管制字体的伸缩
  • 斜度轴 “slnt” (slant):对应字体的 font-style: oblique + angle,管制字体的歪斜
  • 斜体轴 “ital”:对应字体的 font-style: italic,管制字体的歪斜(留神,和 font-style: oblique 是不一样的歪斜)
  • 光学尺寸轴 “opsz”:对应字体的 font-optical-sizing,管制字体的光学尺寸

好吧,可能会有一点点懵,没事,通过一个例子马上就能了解什么意思。

还是利用上述的可变字体,咱们利用 font-variation-settings 实现一个字体粗细的变动的动画:

<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;}
}

成果如下:

其中,其实能够了解为,利用了 font-variation-settings: "wght" 的变动的动画,等同于 font-weight 变动动画:

利用 font-variation-settings 进行字体的多个特色同时变动

OK,那么如果既然是一样的成果,为什么还要多此一举搞个 font-variation-settings 呢?

那是因为 font-variation-settings 除了反对字体的粗细变动外,还反对上述说的注册轴设定的多个款式属性变动,以及 自定义轴 的一些字体款式属性变动。

这次,除了字体粗细外,咱们再增加上 "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;}
}

这次,进行的是字体粗细从 100 到 600,字体伸缩从 60% 到 400% 的动画成果,成果如下:

也就是说,font-variation-settings 是同时反对多个字体款式一起变动的,这一点十分重要。

到这里,其实咱们曾经能够利用这个实现题图所示的成果了,咱们简略革新下,增加多行,再给每行设定一个负的动画提早即可:

<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 简化下代码,下述代码外围就是给每个 li,增加一个雷同的动画 font-variation-settings 动画,并且顺次设置了等差的 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;
    }
}

成果如下:

好,接下来,利用 CSS 3D 简略结构一下 3D 场景即可,残缺的 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 的可变轴 — 注册轴与自定义轴

回归到可变字体自身。下面提到了可变轴这个概念,它们分为 注册轴 自定义轴,英文是:

  • 注册轴 – registered axes
  • 自定义轴 – custom axes

可变字体新格局的外围是可变轴的概念,其形容了字体设计中某一个性的容许变动范畴。

例如‘字重轴’形容了字体的粗细;“宽度轴”形容了字体的宽窄;“斜体轴”形容是否应用斜体字形并且可相应地开关;等。请留神,轴既能够是范畴抉择又能够是开关抉择。字重可能在 1 -999 之间,而斜体可能只是简略的 0 或 1(敞开或关上)。

如标准中所定义,存在两种变形轴,注册轴和自定义轴:

  • 注册轴 最为常见,常见到制订标准的作者认为有必要进行标准化。目前注册的五个轴是字重,宽度,倾斜度,斜体和光学尺寸。

上文其实曾经列举了 5 个注册轴,并且简略介绍了它们的应用。再列举一次:

  1. 字重轴 “wght”:对应 font-weight,管制字体的粗细
  2. 宽度轴 “wdth”:对应 font-stretch,管制字体的伸缩
  3. 斜度轴 “slnt” (slant):对应字体的 font-style: oblique + angle,管制字体的歪斜
  4. 斜体轴 “ital”:对应字体的 font-style: italic,管制字体的歪斜(留神,和 font-style: oblique 是不一样的歪斜)
  5. 光学尺寸轴 “opsz”:对应字体的 font-optical-sizing,管制字体的光学尺寸
  • 自定义轴 实际上是有限的:字体设计师能够定义和界定他们喜爱的任何轴,并且只须要给它一个四个字母的标签以在字体文件格式自身中辨认它。

咱们来看一个 自定义轴 的例子:

<p>Grade</p>
p {
    font-family: "Amstelvar VF", serif;
    font-size: 64px;
    font-variation-settings: 'GRAD' 88;
}

上述 font-family: "Amstelvar VF" 是一个可变字体,而 ‘GRAD’ 属于自定义轴的一个,意为 等级轴

  • 等级轴 ‘GRAD’:“等级”一词指的是字体设计的绝对分量或密度,但与传统的“分量”不同之处在于文本占据的物理空间不会扭转,因而扭转文本等级并不会扭转文本或其四周元素的整体布局。这使得等级成为有用的变动轴,因为它能够变动或动画而不会引起文本自身的回流。

MDN 上有对于扭转 ‘GRAD’ 的值,对应字体变动的一个 DEMO,成果如下:

值得注意的是,自定义轴能够是字体设计师设想的任何设计变动轴。可能有一些会逐步变得相当广泛,随着标准的倒退甚至演变成注册轴。

去哪找可变字体?

OK,如果当初我想在业务中应用一下可变字体,去实现一个成果或者动画,能够上哪里寻找可变字体的资源呢?

这里有一个很不错的网站 — Variable Fonts。

下面收集了十分多的 Variable Fonts,并且列举出了它们在注册轴上反对的字体属性的范畴,譬如反对字重从 100 到 700,咱们能够自在进行调试预览

Can i Use(2022-02-20)

当初可能开始应用可变字体了吗?

截止至明天,Can i Use 的截图:

兼容性曾经十分的不错了,不思考 IE 系列的话能够上到理论的生产环境中去。

最初

目前对于 CSS Font Variation 的相干介绍非常少,如果你对它十分感兴趣,这里还有一篇十分好的文章值得细读:Introduction to variable fonts on the web

本文到此结束,心愿对你有帮忙 :)

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 — iCSS 前端趣闻 😄

更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。

如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。

正文完
 0