『粗上加粗』字体问题定位

本文通过一个问题定位,介绍了使用 @font-face 自定义字体的匹配规则。

背景:

在使用蓝湖自动生成的样式后,出现粗上加粗的问题

1
2
3
4
5
.style_from_lanhu {
font-size: 40px;
font-family: DINPro-Bold, DINPro;
font-weight: bold;
}

,即 DINPro-Bold 叠加 font-weight: bold; 出现更粗的问题。

现象:

  1. macOS 端 Chrome 下,样式不会加粗,样式正常;
  2. macOS 端 Safari 下,粗上加粗,样式异常;
  3. iPhone 端 Safari&Chrome下,粗上加粗,样式异常;

原因:

在我们自定义字体的写法是:

1
2
3
4
5
6
@font-face {
font-family: "DINPro-Bold";
font-style: normal;
font-weight: normal;
src: url("/lib/DINPro-Bold.woff") format("woff");
}

上述写法的含义为: 当 font-family 为 DINPro-Bold,并且 font-style 为 normal,并且 font-weight 为 normal 时,命中 DINPro-Bold.woff 字体。

Safari 很严格地遵守了上述字体命中的规则,当 Safari 看到 .style_from_lanhu 样式时,Safari 的处理为:

  1. font-family: DINPro-Bold 直接命中 DINPro-Bold.woff 字体,DINPro-Bold 后面跟着的 DINPro 被忽略 )
  2. 接 着 font-weight: bold; 再加粗一次,此为粗上加粗的原因。

修改方式:

将 @font-face 中的 font-weight: normal; 修改为 font-weight: bold; ,即:

1
2
3
4
5
6
@font-face {
font-family: "DINPro-Bold";
font-style: normal;
font-weight: bold;
src: url("/lib/DINPro-Bold.woff") format("woff");
}

修改后 font-family: DINPro-Bold 叠加 font-weight: bold; 两个条件一起,才会命中字体。

至于 macOS 端 Chrome 为什么没严格遵循字体命中规则,原因暂未知。

对比 sketch 生成的代码:

为什么 sketch 生成的样式代码如此简洁,蓝湖却要多此一举多生成几行呢?

对比下区别

1
2
3
4
5
6
7
8
9
.style_from_sketch {
font-family: DINPro-Bold;
font-size: 40px;
}
.style_from_lanhu {
font-size: 40px;
font-family: DINPro-Bold, DINPro;
font-weight: bold;
}

个人推测是蓝湖为了兼容 @font-face 的另一种写法,也是更主流的一种写法,即 family:DINPro && weight:bold 命中 DINPro-Bold.woff 字体。

1
2
3
4
5
6
@font-face {
font-family: "DINPro";
font-style: normal;
font-weight: bold;
src: url("/lib/DINPro-Bold.woff") format("woff");
}

另一方面,自定义字体在未下载下来的时候,有一个默认的 bold 效果,整体样式不会太突兀。

更进一步

现代浏览器更推荐用woff2,体积比woff小接近40%(DINPro-Bold.woff 43KB –> DINPro-Bold.woff2 28KB)。下面附上推荐的写法。现有woff文件推荐使用 transfonter.org 转换。

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
@font-face {
font-family: "DINPro-Light";
src: url("/lib/DINPro-Light.woff2") format("woff2"),
url("/lib/DINPro-Light.woff") format("woff");
font-weight: 300;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: "DINPro";
src: url("/lib/DINPro-Regular.woff2") format("woff2"),
url("/lib/DINPro-Regular.woff") format("woff");
font-weight: normal;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: "DINPro-Medium";
src: url("/lib/DINPro-Medium.woff2") format("woff2"),
url("/lib/DINPro-Medium.woff") format("woff");
font-weight: 500;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: "DINPro-Bold";
src: url("/lib/DINPro-Bold.woff2") format("woff2"),
url("/lib/DINPro-Bold.woff") format("woff");
font-weight: bold;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: "DINPro-Black";
src: url("/lib/DINPro-Black.woff2") format("woff2"),
url("/lib/DINPro-Black.woff") format("woff");
font-weight: 900;
font-style: normal;
font-display: swap;
}

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
@font-face {
font-family: "DINPro";
src: url("/lib/DINPro-Light.woff2") format("woff2"),
url("/lib/DINPro-Light.woff") format("woff");
font-weight: 300;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: "DINPro";
src: url("/lib/DINPro-Regular.woff2") format("woff2"),
url("/lib/DINPro-Regular.woff") format("woff");
font-weight: normal;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: "DINPro";
src: url("/lib/DINPro-Medium.woff2") format("woff2"),
url("/lib/DINPro-Medium.woff") format("woff");
font-weight: 500;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: "DINPro";
src: url("/lib/DINPro-Bold.woff2") format("woff2"),
url("/lib/DINPro-Bold.woff") format("woff");
font-weight: bold;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: "DINPro";
src: url("/lib/DINPro-Black.woff2") format("woff2"),
url("/lib/DINPro-Black.woff") format("woff");
font-weight: 900;
font-style: normal;
font-display: swap;
}

参考:

https://justineo.github.io/slideshows/font/#/3/1

https://www.mulingyuer.com/archives/126/

https://fonts.google.com/knowledge/using_type/using_web_fonts

https://www.zachleat.com/web/css-tricks-web-fonts/

https://css-tricks.com/the-best-font-loading-strategies-and-how-to-execute-them/#loading-fonts-with-self-hosted-fonts

https://www.zachleat.com/web/comprehensive-webfonts/#font-display

https://transfonter.org/

https://drafts.csswg.org/css-fonts-3/#font-face-rule

https://drafts.csswg.org/css-fonts-3/#font-matching-algorithm

https://developer.mozilla.org/zh-CN/docs/Web/CSS/@font-face

https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#common_weight_name_mapping

『粗上加粗』字体问题定位

https://lvdawei.com/post/font-face-bugfix/

Author

David Lv

Posted on

2022-04-29

Updated on

2022-07-15

Licensed under