前言

font-family 虽然只是一个 CSS 属性, 但是牵连许多东西, 所以独立一篇来讲.

网站一般上会使用 Google Fonts 作为 font-family, 下面会以一个 Google Fonts 为例子. 逐步解析它背后的 CSS 知识.

Pick a Google Font

到官网 fonts.google.com, 随便选一个 font 作为 font-family.

我选了 material 的 Roboto.

Select font-style and font-weight

知识点

1. 不是每个字体都有支持 Italic

2. 不是每个字体都支持 100 – 900 的 weight

3. 网站有使用到的才选择. 每一个 style 和 weight 都是一份字体文件, 下载越多越慢.

4. 常用的 weight 300, 400, 500, 700, Italic 尽量就别用了

作为示范, 我选了 normal 300, 400, 500, 700 和 Italic 400

右边点击 select, 就可以看见 selected 的 style 和 weight 了

Import CSS

它有 2 种 import 的 way.

第一是在 HTML 放 <link>

第二是在 CSS 放 @import, 我个人喜好是用这个

它其实就是一个去加载 CSS 的 URL

知识点

1. 以前是 css, 现在是 css2 版本不同了, Google 对字体做了一次改版, 如果你切换到 css 会拿到旧版本的字体

2. selected font-style

3. selcted font-weight

4. font-display 这个下面会详解讲它的作用.

如果有多个字体的话, 它的 URL 长这样

我加多了一个字体 Open Sans, 没有什么特别的. 只是 query param 多了 1 set family 而已 (相同 query param key 不常见, 但其实是符合规范的. 题外话: ASP.NET Core 获取 same query param key)

Set font-family Style

下方有声明如何使用在 Style

sans-serif 是 Roboto 的 fallback 字体.

效果

Import 的 CSS 做了什么?

上面有一个关键就是 Import CSS, 它做了啥?

用 DevTools 可以看到, 它加载了一个 CSS Style, 里面有 @font-face

@font-face

@font-face 是 CSS 语法. 用来 define 一个字体. 来看看它的属性.

@font-face {
font-family: 'Roboto';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1Mu51xFIzIFKw.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

font-family, style, weight 就不多说了.

src

字体文件 URL. 之前在 W3Schools 学习笔记 (3) – CSS Web Fonts 中有提过.

字体要渲染需要 TTF/OTF, WOFF 或者 WOFF2 文件.

所以, @font-face 只是定义了加载路径, 游览器会依据这个路径再去加载字体文件, 才能渲染.

另外, Google Fonts 是可以 self host 的哦, 通过 google-webfonts-helper 下载字体, 或者到官网下载 (but 官网的是 TTF, helper 是 WOFF2), 然后把 .woff2 或 .ttf 文件放到自己 server, src 改成 link to 自己 server 路径就可以了.

font-display

参考:

页面字体闪一下?这两个标准能帮到你

CSS-Tricks – font-display

它有好几个值

auto: 依据游览器行为, 一般是 block

block: 上面说了游览器需要加载 .woff 文件, 这段期间字体要如何展现呢?

block 就是不显示. 直接给一个白色, 完全看不到字, 直到字体下载完成渲染后才显示. 这个体验叫 FOIT (Flash Of Invisible Text), 很少人这样做的, 体验不好

swap: 在等待加载的时候, 先显示 fallback 字体, 等加载完成才显示最终字体. 这个体验叫 FOUT (Flash Of Unstyled Text), 大部分人都这样做 (虽然体验也不是 100% 的好)

fallback: block 和 swap 的折中方案, 会先 block 100ms 左右, 然后 3秒 swap, 如果 3 秒后还没有加载成功, 那么就一直用 fallback 的. 考虑到 3 秒后用户已经开始阅读内容了, 这时切换字体会很明显跳一下, 体验扣很多分

optional: 和 fallback 类似. 只是把权力交给游览器依据下载速度决定是否去加载字体.

block, swap, fallback, optional 可以理解为你多在意自定义字体. block 就是一定要用自定义字体, 其它的连看都不可以. swap 就是可以先看 fallback 但最后一定要看到自定义

fallback 就不一定要看到自定义, 加载快才看. optional 顾名思义, 更加不注重了. 大部分人都会用 swap.

unicode-range 没有认真研究. 从 Google Fonts 的 @font-face 可以看到, 同一个 family, style, weight 会有很多版本的 unicode-range.

提醒:

不同 font-family, 不同 style, 不同 weight, 不同 unicode 都需要新的一个 @font-face 哦. 所以 @font-face 会有很多很多的.

CSS Font Loading API

参考:

stackoverflow – How to be notified once a web font has loaded

Medium – Getting started with CSS Font Loading

上面说到, @font-face 定义了 .woff2 的加载路径, 然后游览器去加载文件后渲染.

font-display swap 会先显示 fallback 的字体, 然后切换, 所以字体的 size 会改变.

如果我们依赖这个字体的 width 怎么办呢? 虽然可以用 ResizeObserver 监听, 但它不是最好的. 更好的是用 document.fonts

document.fonts 是一个 iterable 对象. 它记入了所有 @font-face 的内容.

for (const font of document.fonts) {
console.log("font", font);
}

遍历后可以看到所以 @font-face 定义的字体

下面 2 个监听方式

document.fonts.ready.then(() => {
console.log("all loaded");
}); [...document.fonts][0].loaded.then(() => {
console.log("specify font loaded");
});

第一个是监听所有 font 加载完毕

第二个是指定某一个 font 加载完毕

JS 动态加载 font-face

上面都是靠 CSS @font-face 去加载的. JavaScript 也是有 API 可以动态加载 font 的哦.

注释 CSS

/*
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2)
format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
U+FEFF, U+FFFD;
}
*/

JavaScript

document.querySelector("button")!.addEventListener("click", () => {
// define
const robotoFontFace = new FontFace(
"Roboto",
`url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2)
format("woff2")`,
{
display: "swap",
style: "normal",
weight: "400",
unicodeRange: `U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
U+FEFF, U+FFFD`,
}
); // load
robotoFontFace.load().then(() => {
// add to document.fonts
document.fonts.add(robotoFontFace); // set style
document.querySelector("h1")!.style.fontFamily = `Roboto`;
});
});

new FontFace 类似 CSS 的 @font-face. 照搬而已.

定义好 FontFace 把它添加到 document.fonts 里面去. 然后就可以使用了.

我上面调用 load 只是一个示范而已. 其实只要添加进了 document.fonts 它就会自动去加载了.

和 font-family 有关的文章

Figma 学习笔记 – Text

webpack – postcss-font-magician

总结

1. font-family 需要 .woff2 文件 (.woff2 文件就是 font 的设计文档, 有些是版权的哦, 不可以随便用)

2. CSS Style @font-face 只定义了加载路径

3. 游览器加载 font 时, font-display 控制体验

4. JS 也有 API 可以设置 font-face 和监听 font rendered.

中文 font

参考:

Web 开发中文字体指南

Github – font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif

CSS - Tracks – System Font Stack

[前端基础]font-family 详解

英文字体有非常多的选择, 电脑没有可以去下载一个就搞定了.

但中文就不行了. 中文 file 太大了, 随便一个就可能要 10mb.

所以网站要支持中文, 就只能用电脑已有的字体.

Safe fonts

下面是英文的 safe fonts

那中文呢...不好意思...没有通用的.

不同的 OS 用的中文字体是不同的, 而我们需要兼顾 4 个 OS, Windows, macOS, IOS, Android.

font-family

system-ui 这个是所有 OS 通用的字体 (比较新, 如果要兼容一些老旧设备需要配上下面几个)

-apple-system 这个是苹果机 IOS, macOS 的字体.

BlinkMacSystemFont 这个是早年的 macOS Chrome 的字体

Segoe UI for Windows

Noto Sans for Android (在 Android. Noto for chinese, Roboto for english)

full version

所以目前最常见的方案是

先放一个 english pretty 字体.

然后跟着下面这句

my-pretty-font,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"

这样就可以保证中英文都支持美美了.

各大网站参考

Boostrap

system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"

TailwindCSS

Inter var,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji

博客园

"PingFang SC","Microsoft YaHei","Helvetica Neue","Helvetica","Arial",sans-serif;

Tesla

"Gotham SSm", "PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif

Apple

"SF Pro SC", "HanHei SC", "SF Pro Text", "Myriad Set Pro", "SF Pro Icons", "Apple Legacy Chevron", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif

Microsoft

"Segoe UI",SegoeUI,"Helvetica Neue",Helvetica,Arial,sans-serif

Github

-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"

Medium

source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif

可以看到 Boostrap, TailwindCSS, Github 是比较完整的. 像 Microsoft 根本不鸟 IOS, macOS, Apple 也没放 Segoe UI.

CSS – Font Family的更多相关文章

  1. 【转载】CSS font关键字属性值的简单研究

    文章转载自 张鑫旭-鑫空间-鑫生活 http://www.zhangxinxu.com/wordpress/ 原文链接:http://www.zhangxinxu.com/wordpress/?p=5 ...

  2. CSS Font知识整理总结

    1.什么是字体 字体是文字的外在形式,就是文字的风格,是文字的外衣.比如行书.楷书.草书,都是一种字体.同样一个字每个人写起来都会有差异,可以说每个人都有一套潜在的字体库.对于web页面来说,字体就是 ...

  3. CSS font 复合属性的顺序

    CSS 参考手册 实例 在一个声明中设置所有字体属性: p.ex1 { font:italic arial,sans-serif; } p.ex2 { font:italic bold 12px/20 ...

  4. CSS font字体知识学习

    字体系列 [1]5种通用字体系列:拥有相似外观的字体系列 serif字体:字体成比例,且有上下短线(衬线字体),包括Times\Georgia\New century Schoolbook sans- ...

  5. css常用的简写技巧_css background简写、css border 简写、css font属性简写等

    css样式中有很多简写方式,比如:设置背景,字体,边框,盒子等.我们都可以把css代码合并为一行,这篇文章将总结有哪些属性支持css简写. 1.背景background属性 background-co ...

  6. css font的简写规则

    font的属性简写里面常用的有5个是可以写在一起的: font-style设定斜体 如:font-style: italic;font-weight设定文字粗细 如:font-weight: bold ...

  7. css font简写规则

    是不是在很很多网站的公共样式中会看到这样的代码?font: 12px/150% Arial, Verdana, "\5b8b\4f53";意思为:字体大小/行高 字体族 " ...

  8. CSS Font文字样式

    font-style: /* 文字样式 italic(倾斜) | normal */ font-weight: /* 文字是否加粗 bold | normal(正常) */ font-size: /* ...

  9. CSS| font property

    字體屬性 常用的CSS字体名称 宋体 SimSun 黑体 SimHei 微软雅黑 Microsoft YaHei 微软正黑体 Microsoft JhengHei 新宋体 NSimSun 新细明体 P ...

  10. CSS font系列

    font-family font-family: Verdana,Helvetica,Arial,"Microsoft YaHei",sans-serif; font-family ...

随机推荐

  1. 3.5 Y84-64的流水线实现

    我们终于准备好要开始本章的主要任务--设计一个流水线化的Y86-64处理器.首先,对顺序的SEQ处理器做一点小的改动,将PC的计算挪到取指阶段.然后,在各个阶段之间加上流水线寄存器.到这个时候,我们的 ...

  2. [oeasy]python0008_输出h字符_REPL_引号_括号_什么是函数

    输出h字符_REPL_引号_括号_什么是函数 回忆上次内容 上次 继续在游乐场里 玩耍 键盘按键 作用 ↑ 上一条指令 ↓ 下一条指令 ← 光标 向左移动 一格 → 光标 向右移动 一格 ctrl + ...

  3. ArchLinux Vmware安装指北

    ArchLinux Vmware安装指北 在本文开始之前,首先允许我提前声明一点,Arch Linux的安装并不算难,但是绝对也算不上简单,中间的安装可能会遇到很多问题,本篇文章不能保证完全贴合你的真 ...

  4. for循环以及常用的遍历(迭代)用法

    for循环以及常用的遍历(迭代)用法   概念:(概念才是高楼的地基!) for循环是一个计次循环,一般运用在循环次数已知的情况下.通常适用于枚举或遍历序列,以及迭代序列中的元素. 注意*:迭代变量用 ...

  5. SpringBoot实战:Spring Boot接入Security权限认证服务

    引言 Spring Security 是一个功能强大且高度可定制的身份验证和访问控制的框架,提供了完善的认证机制和方法级的授权功能,是一个非常优秀的权限管理框架.其核心是一组过滤器链,不同的功能经由不 ...

  6. 2024-07-24:用go语言,给定一个整数数组 nums,其中至少包含两个元素。 可以根据以下规则执行操作:选择最前面两个元素删除、选择最后两个元素删除,或选择第一个和最后一个元素删除。 每次操作

    2024-07-24:用go语言,给定一个整数数组 nums,其中至少包含两个元素. 可以根据以下规则执行操作:选择最前面两个元素删除.选择最后两个元素删除,或选择第一个和最后一个元素删除. 每次操作 ...

  7. 嘿,我使用了mp的自连接+分页查询之后,再使用条件查询居然失效了。

    原因:我想通过自连接查询将一个表的两条数据放在一起,为此我重写了mp的分页查询 IPage<Indi> selectIndiShow(IPage<Indi> page, @Pa ...

  8. 初看vue3源码

    因为工作的原因又回到了vue的领域,需要加深对vue和vue生态的了解 也许平时比较多人手机看别人解析怎么看vue源码的,自己动手看vue源码的还是比较少,这次我想自己动手看看 首先 吧代码获取到本地 ...

  9. vue导入项目缺少依赖‘node_modules’

    从git下载好的项目,导入vue时提示'node_modules'依赖 则需要在你的项目包下面找是否有package-lock.json文件,如: 如果有,但是依旧报错,直接删除package-loc ...

  10. NVIDIA公司在实体机器人上的第一步尝试 —— Nova Cater AMR —— 九号机器人与英伟达联合开发的自动驾驶研发平台“Nova Cater AMR(简称:NC)”

    相关: https://www.leiphone.com/category/robot/Hgy9i8azqGncESIB.html Nova Cater AMR是一款仓储运货机器人,可以应用在仓储物流 ...