广告位联系
返回顶部
分享到

CSS font-variation可变字体的魅力(实例详解)

css 来源:互联网 作者:秩名 发布时间:2022-03-05 08:02:58 人浏览
摘要

天,在 CodePen 上看到一个很有意思的效果 --GSAP 3 ETC Variable Font Wave,借助了 JS 动画库 GSAP 实现,一起来看看: 我寻思着能否使用 CSS 复刻一版,鼓捣了一会,利用纯 CSS 成功实现了原效

天,在 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 的变化动画:

1

2

3

4

5

6

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

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

}

看看结果:

并没有我们想象中的,因为字体粗细从 100 到 600,所以字体依次变粗的情况,一共只有两种字重:

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

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

可变字体的多样性

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

加载可变字体的语法与其他 web 字体非常相似,但有一些显著的差异,这些差异是通过对现代浏览器中可用的传统 @font-face 语法的升级提供的。 基本语法是相同的,但是字体技术是不一样的,并且可变字体可以提供像对 font-weight 和 font-stretch 等描述符的允许范围,而不是根据加载的字体文件来命名。 下面,我们将加载一个支持字体粗细从 100 到 900,字体伸缩变形支持从 10% 到 400% 的 AnyBody 可变字体。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@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: 100 到 font-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 实现一个字体粗细的变化的动画:

1

<p>Anybody</p>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

@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" 的变化,也就是字体的伸缩。

1

<p>Anybody</p>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

@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 是同时支持多个字体样式一起变化的,这一点非常重要。

到这里,其实我们已经可以利用这个实现题图所示的效果了,我们简单改造下,添加多行,再给每行设定一个负的动画延迟即可:

1

2

3

4

5

6

7

8

9

10

11

12

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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 代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

@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 个注册轴,并且简单介绍了它们的使用。再罗列一次:

  • 字重轴 "wght":对应 font-weight,控制字体的粗细
  • 宽度轴 "wdth":对应 font-stretch,控制字体的伸缩斜度轴 "slnt" (slant):对应字体的 font-style: oblique + angle,控制字体的倾斜
  • 斜体轴 "ital":对应字体的 font-style: italic,控制字体的倾斜(注意,和 font-style: oblique 是不一样的倾斜)
  • 光学尺寸轴 "opsz":对应字体的 font-optical-sizing,控制字体的光学尺寸自定义轴实际上是无限的:字体设计师可以定义和界定他们喜欢的任何轴,并且只需要给它一个四个字母的标签以在字体文件格式本身中识别它。

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

1

<p>Grade</p>

1

2

3

4

5

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 系列的话可以上到实际的生产环境中去。

最后

本文到此结束,希望对你有帮助 


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://www.jb51.net/css/813895.html
相关文章
  • CSS3浏览器兼容的介绍

    CSS3浏览器兼容的介绍
    一、浏览器兼容 1.1、概要 世界上没有任何一个浏览器是一样的,同样的代码在不一样的浏览器上运行就存在兼容性问题。不同浏览器其内核
  • CSS元素定位之通过元素的标签或者元素的id、cl

    CSS元素定位之通过元素的标签或者元素的id、cl
    大部分人在使用selenium定位元素时,用的是xpath元素定位方式,因为xpath元素定位方式基本能解决定位的需求。xpath元素定位方式更直观,更好
  • 微信小程序纯CSS实现无限弹幕滚动效果

    微信小程序纯CSS实现无限弹幕滚动效果
    啥也不说,先上效果图 实现背景 产品:我们需要一个弹幕滚动效果,类似于微博热搜那种实时评论,但是我们的数据是固定的20条,你让他
  • 使用CSS构建强大且酷炫的粒子动画效果

    使用CSS构建强大且酷炫的粒子动画效果
    粒子动画,顾名思义,就是页面上存在大量的粒子构建而成的动画。传统的粒子动画主要由 Canvas、WebGL 实现。 当然,不使用 HTML + CSS 的主要
  • flex:1的详细介绍

    flex:1的详细介绍
    简单的来说一下在别人问你这个问题的时候怎么来回答它 前端新人,如有错误求大佬指出~求教???? 情景复现 大佬提问:你知道flex: 1;的更深
  • 新的CSS伪类函数 :is 和 :where()示例介绍

    新的CSS伪类函数 :is 和 :where()示例介绍
    在编写 CSS 时,有时可能会使用很长的选择器列表来定位具有相同样式规则的多个元素。例如,如果您想对标题中的 b 标签进行颜色调整,我
  • 纯CSS打字动画的实现方法

    纯CSS打字动画的实现方法
    在一些技术网站中,经常会看到这样一种展示效果:逐个显示一段文本中的字符,模拟出一种打字的效果。通过这种方式可以显著地提升网
  • 实现el-form每行显示两列底部按钮居中效果的教程

    实现el-form每行显示两列底部按钮居中效果的教程
    el-form 每行显示两列,底部按钮居中 问题: 以前的解决办法是:el-col,el-row。但是这里只有一个el-form-item的label数据是已知的,其余项都是循
  • CSS实现六边形的图片效果的代码

    CSS实现六边形的图片效果的代码
    前言 在CodePen上看到一个有意思的效果: 这个效果的难点在于六边形的绘制, 那么接下来我们就一起来看下作者是怎么实现他的吧 实现思路
  • CSS浮动引起的高度塌陷问题的详细介绍

    CSS浮动引起的高度塌陷问题的详细介绍
    正常页面布局 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 style *{ margin:0; padding: 0; } .content{ width:400px; border:1px solid #000; } .box{ width:200px;
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计