【你不一定知道的CSS】font-family 继承失效了?

4,973 阅读3分钟

CSS 继承

从 MDN 上可以看到,当元素的一个继承属性 (inherited property)没有指定值时,则取父元素的同属性的计算值(computed value)

比如 color 属性就是继承属性,给父级元素设置了 color,则子元素会继承,如下:

今天来聊一个有意思的属性——font-family

font-family——继承失效了?

CSS 属性 font-family 允许您通过给定一个有先后顺序的,由字体名或者字体族名组成的列表来为选定的元素设置字体。

属性 font-family 列举一个或多个由逗号隔开的字体族,语法如下:

/* 一个字体族名和一个通用字体族名 */
font-family: "Gill Sans Extrabold", sans-serif;
font-family: "Goudy Bookletter 1911", sans-serif;

/* 仅有一个通用字体族名 */
font-family: serif;
font-family: sans-serif;
font-family: monospace;
font-family: cursive;
font-family: fantasy;
font-family: system-ui;
font-family: emoji;
font-family: math;
font-family: fangsong;

/* 全局值 */
font-family: inherit;
font-family: initial;
font-family: unset;

font-family 是一个继承属性,比如,我给上面例子 .parent 添加 font-family: serif;,子元素也会继承它的属性值

但是,我们给子元素的 font-family 随便设置一个值 test,这实际上是一个无效的字体

.child {
  font-family: test;
}

奇怪的事情来了,浏览器竟然识别不出来这是一个无效的值,计算值的结果还是 test(这里猜测因为 font-family 可以通过 @font-face 自定义设置,所以浏览器无法知道它是无效的),但实际上效果已经直接降级到浏览器的默认值了,而不是父级元素设置的值,这跟我们认知的还不太一样....

假如我们设置子元素的样式如下,即在 test 之后再设置一个字体 Gill Sans

.child {
  font-family: test, "Gill Sans";
}

这个时候,可以看到降级到 Gill Sans

demo 地址

CSS 冷知识——font-family 的值

这也是一个意外发现,因为假如我设置上面的 font-family 的值为 123test 的时候,我发现子元素可以继承父元素的 font-family,这又是为什么呢?

在 MDN 上可以看到,font-family 的语法是

<family-name>
where 
<family-name> = <string> | <custom-ident>+

其中字符串很容易理解,那 custom-ident 是什么呢?还是 MDN

指用户自定义字符串标识符。一种CSS 数据类型;要区分大小写,值不能有任何歧义。

具体的语法可以查看上面的链接,这里就不细说了。关注点在最后一句“值不能有任何歧义”,其中规定了无效的标识符有如下,而我刚好踩到了第一个坑里去了。

34rem             第一个字符不能是数字
-12rad            第一个字符连字符后不能跟数字
bili.bob          只有字母数字、连字符-、下划线_不需要转义
--toto            第一个字符不能为连字符后跟连字符
'bilibob'         不能用单引号包起来,这是一个字符串类型
"bilibob"         不能用双引号包起来,这是一个字符串类型

总结

假如你设置了 font-family,而且不知道自己设置的字体能不能在所有的浏览器上都能生效的时候,推荐总写一个兜底的字体。否则假如该字体不生效的话,该元素并不会自动继承你在 body 或者 html 元素等父级元素中设置的兜底值