前言

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. 【解决方案】智能UI自动化测试

    你的UI自动化追得上业务的变更和UI更迭吗?当今瞬息万变的时代,成千上万的App围绕着现代人生活的点点滴滴.为了满足用户的好的体验和时刻的新鲜感,这些App需要时刻保持变化,也给 UI自动化落地实施带 ...

  2. [oeasy]python0045_转化为10进制数_int_integrate_integer_entire_整数

    转化为10进制 回忆上次内容 上这次总结了四种进制 函数名 对应单词 进制类型 数字事例 前缀 bin() binary 2 0b1100001 0b oct() octal 8 0o141 0o h ...

  3. 开源照片管理神器 PhotoPrism 安装和使用教程

    如今我们每个人都积累了海量的照片和视频,做自媒体的 UP 主们积累的照片和视频数量可能更多.面对这么多的照片和视频,我们该如何管理呢? 之前我一直用谷歌相册,因为它有很多优势,比如无限空间,支持智能整 ...

  4. Python和RPA网页自动化-让select标签下拉框选择指定文本的方法

    以影刀商城(https://shop.yingdao.com/webOperations/index)为例: 该下拉框有<select>标签.分别使用Python和RPA网页自动化让下拉框 ...

  5. 【SpringMVC】09 对JSON的应用

    前面JavaWeb的JSON回顾: https://www.cnblogs.com/mindzone/p/12820877.html 上面的这个帖子我都还没有实际写进Servlet使用,要Mark一下 ...

  6. 基于 ChatGPT 的聊天软件合集打包分享

      「基于 ChatGPT 的聊天软件合集打包」 链接:https://pan.quark.cn/s/ef1f5e9c48e4 BotGem(原名AMA) 官网:https://botgem.com/ ...

  7. baselines算法库common/vec_env/vec_env.py模块分析

    common/vec_env/vec_env.py模块内容: import contextlib import os from abc import ABC, abstractmethod from ...

  8. Inno Setup 寻找 AppId 的方法

    背景 有时候打包后,会遗失AppId.这样会导致下一次打包时没办法和之前统一.为了避免这个问题,所以最好是打包时记下来,可以根据注册表去查 解决办法 可以根据任意查找注册表的工具,我这里使用 Regi ...

  9. 如何在通用异常处理时获取到方法名称(获取注解参数JoinPoint)

    1.背景 很多时候我们在梳理公共异常时,需要获取到接口的而具体名称,便于很好的提示是那个接口错误了 2.实现逻辑 1.在controller方法上的注解上写方法名称,一般使用了swagger都有方法名 ...

  10. C#开发的全屏图片切换效果应用 - 开源研究系列文章 - 个人小作品

    这天无聊,想到上次开发的图片显示软件< PhotoNet看图软件 >,然后想到开发一个全屏图片切换效果的应用,类似于屏幕保护程序,于是就写了此博文.这个应用比较简单,主要是全屏切换换图片效 ...